From 5e41738e4c5deca0535f84160bd9bb3ee42393fd Mon Sep 17 00:00:00 2001 From: Michael Pfaff Date: Fri, 9 Aug 2024 03:13:29 -0400 Subject: [PATCH] Improve C API I ran `cargo fmt` on the project, which in hindsight was a poor choice. I'm not correcting it right now. --- Cargo.toml | 2 + c/Cargo.toml | 9 +- c/src/lib.rs | 680 ++++++++--- canvas/Cargo.toml | 2 +- canvas/src/lib.rs | 211 ++-- canvas/src/tests.rs | 2 +- canvas/src/text.rs | 294 +++-- color/src/lib.rs | 23 +- color/src/matrix.rs | 50 +- content/src/clip.rs | 64 +- content/src/dash.rs | 26 +- content/src/dilation.rs | 11 +- content/src/effects.rs | 108 +- content/src/gradient.rs | 92 +- content/src/outline.rs | 142 ++- content/src/pattern.rs | 21 +- content/src/segment.rs | 15 +- content/src/stroke.rs | 121 +- content/src/transform.rs | 20 +- content/src/util.rs | 25 +- demo/android/rust/src/lib.rs | 17 +- demo/common/Cargo.toml | 2 +- demo/common/src/camera.rs | 13 +- demo/common/src/concurrent.rs | 5 +- demo/common/src/device.rs | 38 +- demo/common/src/lib.rs | 240 ++-- demo/common/src/renderer.rs | 124 +- demo/common/src/ui.rs | 671 ++++++----- demo/common/src/window.rs | 4 +- demo/magicleap/Cargo.toml | 2 +- demo/magicleap/src/c_api.rs | 42 +- demo/magicleap/src/lib.rs | 114 +- demo/magicleap/src/magicleap.rs | 108 +- demo/magicleap/src/mocked_c_api.rs | 40 +- demo/native/src/main.rs | 293 +++-- examples/canvas_glutin_minimal/src/main.rs | 52 +- examples/canvas_metal_minimal/src/main.rs | 33 +- examples/canvas_minimal/src/main.rs | 76 +- examples/canvas_moire/src/main.rs | 82 +- examples/canvas_nanovg/Cargo.toml | 2 +- examples/canvas_nanovg/src/main.rs | 1047 +++++++++++------ examples/canvas_text/Cargo.toml | 2 +- examples/canvas_text/src/main.rs | 50 +- examples/canvas_webgl_minimal/src/lib.rs | 13 +- examples/swf_basic/src/main.rs | 41 +- export/src/lib.rs | 35 +- export/src/pdf.rs | 77 +- geometry/src/line_segment.rs | 2 +- geometry/src/rect.rs | 30 +- geometry/src/transform2d.rs | 39 +- geometry/src/transform3d.rs | 34 +- geometry/src/unit_vector.rs | 17 +- geometry/src/vector.rs | 21 +- gl/src/lib.rs | 1036 ++++++++++------ gpu/src/allocator.rs | 315 +++-- gpu/src/lib.rs | 180 +-- lottie/src/lib.rs | 5 +- metal/src/lib.rs | 1238 ++++++++++++-------- renderer/src/allocator.rs | 131 ++- renderer/src/builder.rs | 758 +++++++----- renderer/src/concurrent/executor.rs | 9 +- renderer/src/concurrent/rayon.rs | 5 +- renderer/src/concurrent/scene_proxy.rs | 54 +- renderer/src/gpu/blend.rs | 320 +++-- renderer/src/gpu/d3d11/mod.rs | 2 +- renderer/src/gpu/d3d11/renderer.rs | 1117 +++++++++++------- renderer/src/gpu/d3d11/shaders.rs | 126 +- renderer/src/gpu/d3d9/mod.rs | 2 +- renderer/src/gpu/d3d9/renderer.rs | 687 ++++++----- renderer/src/gpu/d3d9/shaders.rs | 706 +++++++---- renderer/src/gpu/debug.rs | 160 ++- renderer/src/gpu/mod.rs | 2 +- renderer/src/gpu/options.rs | 51 +- renderer/src/gpu/perf.rs | 108 +- renderer/src/gpu/renderer.rs | 1009 +++++++++------- renderer/src/gpu/shaders.rs | 332 ++++-- renderer/src/gpu_data.rs | 101 +- renderer/src/options.rs | 27 +- renderer/src/paint.rs | 343 +++--- renderer/src/scene.rs | 109 +- renderer/src/tile_map.rs | 19 +- renderer/src/tiler.rs | 148 ++- renderer/src/tiles.rs | 10 +- resources/build.rs | 23 +- resources/src/embedded.rs | 6 +- resources/src/lib.rs | 4 +- simd/src/arm/mod.rs | 4 +- simd/src/extras.rs | 10 +- simd/src/scalar/mod.rs | 50 +- simd/src/test.rs | 5 +- simd/src/x86/mod.rs | 20 +- simd/src/x86/swizzle_i32x4.rs | 1024 ++++------------ svg/Cargo.toml | 2 +- svg/src/lib.rs | 187 +-- swf/src/lib.rs | 43 +- swf/src/shapes.rs | 229 ++-- text/Cargo.toml | 2 +- text/src/lib.rs | 147 ++- ui/src/lib.rs | 940 +++++++++------ utils/area-lut/src/main.rs | 13 +- utils/convert/Cargo.toml | 2 +- utils/convert/src/main.rs | 14 +- utils/gamma-lut/src/gamma_lut.rs | 62 +- utils/gamma-lut/src/main.rs | 9 +- utils/svg-to-skia/Cargo.toml | 2 +- utils/svg-to-skia/src/main.rs | 27 +- web_canvas/src/lib.rs | 50 +- webgl/src/lib.rs | 149 +-- 108 files changed, 10547 insertions(+), 6871 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eae6fb47..fab0c4ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,8 +68,10 @@ default-members = [ ] [patch.crates-io] +font-kit = { git = "https://git.pfaff.dev/michael/font-kit" } pathfinder_geometry = { path = "geometry" } pathfinder_simd = { path = "simd" } +skribo = { git = "https://git.pfaff.dev/michael/skribo" } [patch."https://github.com/servo/pathfinder"] pathfinder_content = { path = "content" } diff --git a/c/Cargo.toml b/c/Cargo.toml index 7d8e428c..e6968a74 100644 --- a/c/Cargo.toml +++ b/c/Cargo.toml @@ -6,18 +6,18 @@ edition = "2018" [features] metal = ["dep:core-foundation", "dep:io-surface", "dep:metal", "dep:pathfinder_metal"] +svg = ["dep:pathfinder_svg", "dep:usvg"] [lib] crate-type = ["staticlib", "cdylib"] name = "pathfinder" [dependencies] -font-kit = "0.6" +font-kit = "0.13" foreign-types = "0.3" gl = "0.14" libc = "0.2" simple_logger = "4.3" -usvg = "0.9" [dependencies.log] version = "0.4" @@ -53,6 +53,11 @@ path = "../simd" [dependencies.pathfinder_svg] path = "../svg" +optional = true + +[dependencies.usvg] +version = "0.10" +optional = true [target.'cfg(target_os = "macos")'.dependencies.core-foundation] version = "0.6" diff --git a/c/src/lib.rs b/c/src/lib.rs index 06ecdaa1..dd382f3b 100644 --- a/c/src/lib.rs +++ b/c/src/lib.rs @@ -12,6 +12,7 @@ use font_kit::font::Font; use font_kit::handle::Handle; +use font_kit::metrics::Metrics; use gl; use pathfinder_canvas::{Canvas, CanvasFontContext, CanvasRenderingContext2D, FillStyle, LineJoin}; use pathfinder_canvas::{Path2D, TextAlign, TextBaseline, TextMetrics}; @@ -25,9 +26,6 @@ use pathfinder_geometry::transform3d::{Perspective, Transform4F}; use pathfinder_geometry::vector::{Vector2F, Vector2I}; use pathfinder_gl::{GLDevice, GLVersion}; use pathfinder_gpu::Device; -use pathfinder_resources::ResourceLoader; -use pathfinder_resources::fs::FilesystemResourceLoader; -use pathfinder_resources::embedded::EmbeddedResourceLoader; use pathfinder_renderer::concurrent::executor::SequentialExecutor; use pathfinder_renderer::concurrent::rayon::RayonExecutor; use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; @@ -36,7 +34,11 @@ use pathfinder_renderer::gpu::options::{RendererMode, RendererOptions}; use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::options::{BuildOptions, RenderTransform}; use pathfinder_renderer::scene::Scene; +use pathfinder_resources::embedded::EmbeddedResourceLoader; +use pathfinder_resources::fs::FilesystemResourceLoader; +use pathfinder_resources::ResourceLoader; use pathfinder_simd::default::F32x4; +#[cfg(feature = "svg")] use pathfinder_svg::SVGScene; use std::convert::TryFrom; use std::ffi::CString; @@ -46,6 +48,7 @@ use std::path::PathBuf; use std::ptr::NonNull; use std::slice; use std::str; +#[cfg(feature = "svg")] use usvg::{Options, Tree}; #[cfg(all(target_os = "macos", feature = "metal"))] @@ -64,35 +67,35 @@ pub extern "system" fn init_logging() { // `canvas` -pub const PF_LINE_CAP_BUTT: u8 = 0; -pub const PF_LINE_CAP_SQUARE: u8 = 1; -pub const PF_LINE_CAP_ROUND: u8 = 2; +pub const PF_LINE_CAP_BUTT: u8 = 0; +pub const PF_LINE_CAP_SQUARE: u8 = 1; +pub const PF_LINE_CAP_ROUND: u8 = 2; -pub const PF_LINE_JOIN_MITER: u8 = 0; -pub const PF_LINE_JOIN_BEVEL: u8 = 1; -pub const PF_LINE_JOIN_ROUND: u8 = 2; +pub const PF_LINE_JOIN_MITER: u8 = 0; +pub const PF_LINE_JOIN_BEVEL: u8 = 1; +pub const PF_LINE_JOIN_ROUND: u8 = 2; -pub const PF_TEXT_ALIGN_LEFT: u8 = 0; +pub const PF_TEXT_ALIGN_LEFT: u8 = 0; pub const PF_TEXT_ALIGN_CENTER: u8 = 1; -pub const PF_TEXT_ALIGN_RIGHT: u8 = 2; +pub const PF_TEXT_ALIGN_RIGHT: u8 = 2; -pub const PF_TEXT_BASELINE_ALPHABETIC: u8 = 0; -pub const PF_TEXT_BASELINE_TOP: u8 = 1; -pub const PF_TEXT_BASELINE_HANGING: u8 = 2; -pub const PF_TEXT_BASELINE_MIDDLE: u8 = 3; +pub const PF_TEXT_BASELINE_ALPHABETIC: u8 = 0; +pub const PF_TEXT_BASELINE_TOP: u8 = 1; +pub const PF_TEXT_BASELINE_HANGING: u8 = 2; +pub const PF_TEXT_BASELINE_MIDDLE: u8 = 3; pub const PF_TEXT_BASELINE_IDEOGRAPHIC: u8 = 4; -pub const PF_TEXT_BASELINE_BOTTOM: u8 = 5; +pub const PF_TEXT_BASELINE_BOTTOM: u8 = 5; // `content` -pub const PF_ARC_DIRECTION_CW: u8 = 0; +pub const PF_ARC_DIRECTION_CW: u8 = 0; pub const PF_ARC_DIRECTION_CCW: u8 = 1; // `gl` -pub const PF_GL_VERSION_GL3: u8 = 0; -pub const PF_GL_VERSION_GLES3: u8 = 1; -pub const PF_GL_VERSION_GL4: u8 = 2; +pub const PF_GL_VERSION_GL3: u8 = 0; +pub const PF_GL_VERSION_GLES3: u8 = 1; +pub const PF_GL_VERSION_GL4: u8 = 2; // `renderer` @@ -127,6 +130,23 @@ pub type PFCanvasFontContextRef = NonNull; pub type FKFont = Font; pub type FKFontRef = NonNull; +pub type FKCanvasFormat = font_kit::canvas::Format; +pub type FKCanvasRasterizationOptions = font_kit::canvas::RasterizationOptions; + +#[derive(Clone, Copy)] +#[repr(C)] +pub struct FKMetrics { + pub units_per_em: u32, + pub ascent: f32, + pub descent: f32, + pub line_gap: f32, + pub underline_position: f32, + pub underline_thickness: f32, + pub cap_height: f32, + pub x_height: f32, + pub bounding_box: PFRectF, +} + pub type PFFillStyle = FillStyle; pub type PFFillStyleRef = NonNull; @@ -136,12 +156,14 @@ pub type PFArcDirection = u8; pub type PFTextAlign = u8; pub type PFTextBaseline = u8; +#[derive(Clone, Copy)] #[repr(C)] pub struct PFTextMetrics { pub width: f32, } // `content` +#[derive(Clone, Copy)] #[repr(C)] pub struct PFColorF { pub r: f32, @@ -150,6 +172,7 @@ pub struct PFColorF { pub a: f32, } +#[derive(Clone, Copy)] #[repr(C, align(4))] pub struct PFColorU { pub r: u8, @@ -159,24 +182,28 @@ pub struct PFColorU { } // `geometry` +#[derive(Clone, Copy)] #[repr(C)] pub struct PFVector2F { pub x: f32, pub y: f32, } +#[derive(Clone, Copy)] #[repr(C)] pub struct PFVector2I { pub x: i32, pub y: i32, } +#[derive(Clone, Copy)] #[repr(C)] pub struct PFRectF { pub origin: PFVector2F, pub lower_right: PFVector2F, } +#[derive(Clone, Copy)] #[repr(C)] pub struct PFRectI { pub origin: PFVector2I, @@ -184,13 +211,17 @@ pub struct PFRectI { } /// Row-major order. +#[derive(Clone, Copy)] #[repr(C)] pub struct PFMatrix2x2F { - pub m00: f32, pub m01: f32, - pub m10: f32, pub m11: f32, + pub m00: f32, + pub m01: f32, + pub m10: f32, + pub m11: f32, } /// Row-major order. +#[derive(Clone, Copy)] #[repr(C)] pub struct PFTransform2F { pub matrix: PFMatrix2x2F, @@ -198,14 +229,28 @@ pub struct PFTransform2F { } /// Row-major order. +#[derive(Clone, Copy)] #[repr(C)] pub struct PFTransform4F { - pub m00: f32, pub m01: f32, pub m02: f32, pub m03: f32, - pub m10: f32, pub m11: f32, pub m12: f32, pub m13: f32, - pub m20: f32, pub m21: f32, pub m22: f32, pub m23: f32, - pub m30: f32, pub m31: f32, pub m32: f32, pub m33: f32, + pub m00: f32, + pub m01: f32, + pub m02: f32, + pub m03: f32, + pub m10: f32, + pub m11: f32, + pub m12: f32, + pub m13: f32, + pub m20: f32, + pub m21: f32, + pub m22: f32, + pub m23: f32, + pub m30: f32, + pub m31: f32, + pub m32: f32, + pub m33: f32, } +#[derive(Clone, Copy)] #[repr(C)] pub struct PFPerspective { pub transform: PFTransform4F, @@ -216,8 +261,8 @@ pub struct PFPerspective { pub type PFGLDevice = GLDevice; pub type PFGLDeviceRef = NonNull; pub type PFGLVersion = u8; -pub type PFGLFunctionLoader = extern "C" fn(name: *const c_char, userdata: *mut c_void) - -> *const c_void; +pub type PFGLFunctionLoader = + extern "C" fn(name: *const c_char, userdata: *mut c_void) -> *const c_void; // `gpu` pub type PFGLRenderer = Renderer; pub type PFGLRendererRef = NonNull; @@ -276,7 +321,9 @@ pub type PFRenderTransformRef = NonNull; pub type PFRendererLevel = u8; // `svg` +#[cfg(feature = "svg")] pub type PFSVGScene = SVGScene; +#[cfg(feature = "svg")] pub type PFSVGSceneRef = NonNull; // type layouts @@ -328,7 +375,8 @@ pub static TYPE_LAYOUT_PFSceneProxy: TypeLayout = TypeLayout::of:: #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub static TYPE_LAYOUT_PFMetalDestFramebuffer: TypeLayout = TypeLayout::of::(); +pub static TYPE_LAYOUT_PFMetalDestFramebuffer: TypeLayout = + TypeLayout::of::(); #[no_mangle] pub static TYPE_LAYOUT_PFinternalRenderTransform: TypeLayout = TypeLayout::of::(); @@ -344,7 +392,10 @@ pub static TYPE_LAYOUT_PFinternalVector2F: TypeLayout = TypeLayout::of::, font_context: PFCanvasFontContextRef) -> PFResult { +pub unsafe extern "C" fn PFCanvasInit( + canvas: &mut MaybeUninit, + font_context: PFCanvasFontContextRef, +) -> PFResult { canvas.write(Canvas::new().get_context_2d(font_context.as_ref().clone())); PF_OK } @@ -361,7 +412,9 @@ pub extern "C" fn PFCanvasSetSize(canvas: &mut PFCanvas, size: PFVector2F) -> PF } #[no_mangle] -pub unsafe extern "C" fn PFCanvasFontContextInitWithSystemSource(context: PFCanvasFontContextRef) -> PFResult { +pub unsafe extern "C" fn PFCanvasFontContextInitWithSystemSource( + context: PFCanvasFontContextRef, +) -> PFResult { context.write(CanvasFontContext::from_system_source()); PF_OK } @@ -371,14 +424,15 @@ pub unsafe extern "C" fn PFCanvasFontContextInitWithSystemSource(context: PFCanv /// Note that `font-kit` itself has a C API. You can use this to load fonts from memory with e.g. /// `FKHandleCreateWithMemory()`. #[no_mangle] -pub unsafe extern "C" fn PFCanvasFontContextInitWithFonts(context: PFCanvasFontContextRef, - fonts: NonNull, - font_count: usize) - -> PFResult { +pub unsafe extern "C" fn PFCanvasFontContextInitWithFonts( + context: PFCanvasFontContextRef, + fonts: NonNull, + font_count: usize, +) -> PFResult { let fonts = NonNull::slice_from_raw_parts(fonts, font_count).as_ref(); - context.write(CanvasFontContext::from_fonts(fonts.into_iter().map(|font| { - font.as_ref().clone() - }))); + context.write(CanvasFontContext::from_fonts( + fonts.into_iter().map(|font| font.as_ref().clone()), + )); PF_OK } @@ -420,11 +474,16 @@ pub unsafe extern "C" fn PFCanvasClearRect(mut canvas: PFCanvasRef, rect: PFRect // Drawing text #[no_mangle] -pub unsafe extern "C" fn PFCanvasFillText(mut canvas: PFCanvasRef, - string: *const c_char, - string_len: usize, - position: PFVector2F) -> PFResult { - match canvas.as_mut().fill_text(to_rust_string(&string, string_len), position.to_rust()) { +pub unsafe extern "C" fn PFCanvasFillText( + mut canvas: PFCanvasRef, + string: *const c_char, + string_len: usize, + position: PFVector2F, +) -> PFResult { + match canvas + .as_mut() + .fill_text(to_rust_string(&string, string_len), position.to_rust()) + { Ok(()) => PF_OK, Err(e) => { log::error!("Failed to fill text on canvas: {e:?}"); @@ -434,11 +493,16 @@ pub unsafe extern "C" fn PFCanvasFillText(mut canvas: PFCanvasRef, } #[no_mangle] -pub unsafe extern "C" fn PFCanvasStrokeText(mut canvas: PFCanvasRef, - string: *const c_char, - string_len: usize, - position: PFVector2F) -> PFResult { - match canvas.as_mut().stroke_text(to_rust_string(&string, string_len), position.to_rust()) { +pub unsafe extern "C" fn PFCanvasStrokeText( + mut canvas: PFCanvasRef, + string: *const c_char, + string_len: usize, + position: PFVector2F, +) -> PFResult { + match canvas + .as_mut() + .stroke_text(to_rust_string(&string, string_len), position.to_rust()) + { Ok(()) => PF_OK, Err(e) => { log::error!("Failed to fill text on canvas: {e:?}"); @@ -448,10 +512,15 @@ pub unsafe extern "C" fn PFCanvasStrokeText(mut canvas: PFCanvasRef, } #[no_mangle] -pub unsafe extern "C" fn PFCanvasMeasureText(canvas: PFCanvasRef, - string: *const c_char, - string_len: usize) -> PFTextMetrics { - canvas.as_ref().measure_text(to_rust_string(&string, string_len)).to_c() +pub unsafe extern "C" fn PFCanvasMeasureText( + canvas: PFCanvasRef, + string: *const c_char, + string_len: usize, +) -> PFTextMetrics { + canvas + .as_ref() + .measure_text(to_rust_string(&string, string_len)) + .to_c() } #[no_mangle] @@ -462,10 +531,10 @@ pub unsafe extern "C" fn PFCanvasSetLineWidth(mut canvas: PFCanvasRef, new_line_ #[no_mangle] pub unsafe extern "C" fn PFCanvasSetLineCap(mut canvas: PFCanvasRef, new_line_cap: PFLineCap) { canvas.as_mut().set_line_cap(match new_line_cap { - PF_LINE_CAP_BUTT => LineCap::Butt, + PF_LINE_CAP_BUTT => LineCap::Butt, PF_LINE_CAP_SQUARE => LineCap::Square, - PF_LINE_CAP_ROUND => LineCap::Round, - _ => panic!("Invalid Pathfinder line cap style: {}", new_line_cap), + PF_LINE_CAP_ROUND => LineCap::Round, + _ => panic!("Invalid Pathfinder line cap style: {}", new_line_cap), }); } @@ -475,7 +544,7 @@ pub unsafe extern "C" fn PFCanvasSetLineJoin(mut canvas: PFCanvasRef, new_line_j PF_LINE_JOIN_MITER => LineJoin::Miter, PF_LINE_JOIN_BEVEL => LineJoin::Bevel, PF_LINE_JOIN_ROUND => LineJoin::Round, - _ => panic!("Invalid Pathfinder line join style: {}", new_line_join), + _ => panic!("Invalid Pathfinder line join style: {}", new_line_join), }); } @@ -485,15 +554,21 @@ pub unsafe extern "C" fn PFCanvasSetMiterLimit(mut canvas: PFCanvasRef, new_mite } #[no_mangle] -pub unsafe extern "C" fn PFCanvasSetLineDash(mut canvas: PFCanvasRef, - new_line_dashes: *const f32, - new_line_dash_count: usize) { - canvas.as_mut().set_line_dash(slice::from_raw_parts(new_line_dashes, new_line_dash_count).to_vec()) +pub unsafe extern "C" fn PFCanvasSetLineDash( + mut canvas: PFCanvasRef, + new_line_dashes: *const f32, + new_line_dash_count: usize, +) { + canvas + .as_mut() + .set_line_dash(slice::from_raw_parts(new_line_dashes, new_line_dash_count).to_vec()) } #[no_mangle] -pub unsafe extern "C" fn PFCanvasSetTransform(mut canvas: PFCanvasRef, - transform: *const PFTransform2F) { +pub unsafe extern "C" fn PFCanvasSetTransform( + mut canvas: PFCanvasRef, + transform: *const PFTransform2F, +) { canvas.as_mut().set_transform(&(*transform).to_rust()); } @@ -518,10 +593,12 @@ pub unsafe extern "C" fn PFCanvasSetLineDashOffset(mut canvas: PFCanvasRef, new_ } #[no_mangle] -pub unsafe extern "C" fn PFCanvasFontContextGetFontByPostScriptName(context: PFCanvasFontContextRef, - postscript_name: *const c_char, - postscript_name_len: usize, - font_dst: FKFontRef) -> PFResult { +pub unsafe extern "C" fn PFCanvasFontContextGetFontByPostScriptName( + context: PFCanvasFontContextRef, + postscript_name: *const c_char, + postscript_name_len: usize, + font_dst: FKFontRef, +) -> PFResult { let name = to_rust_string(&postscript_name, postscript_name_len); match context.as_ref().get_font_by_postscript_name(name) { Ok(font) => { @@ -535,11 +612,6 @@ pub unsafe extern "C" fn PFCanvasFontContextGetFontByPostScriptName(context: PFC } } -#[no_mangle] -pub unsafe extern "C" fn FKFontDeinit(font: FKFontRef) { - font.drop_in_place(); -} - #[no_mangle] pub unsafe extern "C" fn PFCanvasSetFont(mut canvas: PFCanvasRef, font: FKFontRef) -> PFResult { match canvas.as_mut().set_font(font.as_ref().clone()) { @@ -557,17 +629,22 @@ pub unsafe extern "C" fn PFCanvasSetFontSize(mut canvas: PFCanvasRef, new_font_s } #[no_mangle] -pub unsafe extern "C" fn PFCanvasSetTextAlign(mut canvas: PFCanvasRef, new_text_align: PFTextAlign) { +pub unsafe extern "C" fn PFCanvasSetTextAlign( + mut canvas: PFCanvasRef, + new_text_align: PFTextAlign, +) { canvas.as_mut().set_text_align(match new_text_align { PF_TEXT_ALIGN_CENTER => TextAlign::Center, - PF_TEXT_ALIGN_RIGHT => TextAlign::Right, - _ => TextAlign::Left, + PF_TEXT_ALIGN_RIGHT => TextAlign::Right, + _ => TextAlign::Left, }); } #[no_mangle] -pub unsafe extern "C" fn PFCanvasSetTextBaseline(mut canvas: PFCanvasRef, - new_text_baseline: PFTextBaseline) -> PFResult { +pub unsafe extern "C" fn PFCanvasSetTextBaseline( + mut canvas: PFCanvasRef, + new_text_baseline: PFTextBaseline, +) -> PFResult { canvas.as_mut().set_text_baseline(match new_text_baseline { PF_TEXT_BASELINE_ALPHABETIC => TextBaseline::Alphabetic, PF_TEXT_BASELINE_TOP => TextBaseline::Top, @@ -587,10 +664,14 @@ pub unsafe extern "C" fn PFCanvasSetFillStyle(mut canvas: PFCanvasRef, fill_styl } #[no_mangle] -pub unsafe extern "C" fn PFCanvasSetStrokeStyle(mut canvas: PFCanvasRef, - stroke_style: PFFillStyleRef) { +pub unsafe extern "C" fn PFCanvasSetStrokeStyle( + mut canvas: PFCanvasRef, + stroke_style: PFFillStyleRef, +) { // FIXME(pcwalton): Avoid the copy? - canvas.as_mut().set_stroke_style(stroke_style.as_ref().clone()) + canvas + .as_mut() + .set_stroke_style(stroke_style.as_ref().clone()) } /// This function deinitializes the path. If you wish to use the path again, clone it first. @@ -632,40 +713,51 @@ pub unsafe extern "C" fn PFPathLineTo(mut path: PFPathRef, to: PFVector2F) { } #[no_mangle] -pub unsafe extern "C" fn PFPathQuadraticCurveTo(mut path: PFPathRef, - ctrl: PFVector2F, - to: PFVector2F) { - path.as_mut().quadratic_curve_to(ctrl.to_rust(), to.to_rust()) +pub unsafe extern "C" fn PFPathQuadraticCurveTo( + mut path: PFPathRef, + ctrl: PFVector2F, + to: PFVector2F, +) { + path.as_mut() + .quadratic_curve_to(ctrl.to_rust(), to.to_rust()) } #[no_mangle] -pub unsafe extern "C" fn PFPathBezierCurveTo(mut path: PFPathRef, - ctrl0: PFVector2F, - ctrl1: PFVector2F, - to: PFVector2F) { - path.as_mut().bezier_curve_to(ctrl0.to_rust(), ctrl1.to_rust(), to.to_rust()) +pub unsafe extern "C" fn PFPathBezierCurveTo( + mut path: PFPathRef, + ctrl0: PFVector2F, + ctrl1: PFVector2F, + to: PFVector2F, +) { + path.as_mut() + .bezier_curve_to(ctrl0.to_rust(), ctrl1.to_rust(), to.to_rust()) } #[no_mangle] -pub unsafe extern "C" fn PFPathArc(mut path: PFPathRef, - center: PFVector2F, - radius: f32, - start_angle: f32, - end_angle: f32, - direction: PFArcDirection) { +pub unsafe extern "C" fn PFPathArc( + mut path: PFPathRef, + center: PFVector2F, + radius: f32, + start_angle: f32, + end_angle: f32, + direction: PFArcDirection, +) { let direction = match direction { - PF_ARC_DIRECTION_CW => ArcDirection::CW, + PF_ARC_DIRECTION_CW => ArcDirection::CW, PF_ARC_DIRECTION_CCW => ArcDirection::CCW, - _ => panic!("Invalid Pathfinder arc direction: {}", direction), + _ => panic!("Invalid Pathfinder arc direction: {}", direction), }; - path.as_mut().arc(center.to_rust(), radius, start_angle, end_angle, direction) + path.as_mut() + .arc(center.to_rust(), radius, start_angle, end_angle, direction) } #[no_mangle] -pub unsafe extern "C" fn PFPathArcTo(mut path: PFPathRef, - ctrl: PFVector2F, - to: PFVector2F, - radius: f32) { +pub unsafe extern "C" fn PFPathArcTo( + mut path: PFPathRef, + ctrl: PFVector2F, + to: PFVector2F, + radius: f32, +) { path.as_mut().arc_to(ctrl.to_rust(), to.to_rust(), radius) } @@ -675,13 +767,21 @@ pub unsafe extern "C" fn PFPathRect(mut path: PFPathRef, rect: PFRectF) { } #[no_mangle] -pub unsafe extern "C" fn PFPathEllipse(mut path: PFPathRef, - center: PFVector2F, - axes: PFVector2F, - rotation: f32, - start_angle: f32, - end_angle: f32) { - path.as_mut().ellipse(center.to_rust(), axes.to_rust(), rotation, start_angle, end_angle) +pub unsafe extern "C" fn PFPathEllipse( + mut path: PFPathRef, + center: PFVector2F, + axes: PFVector2F, + rotation: f32, + start_angle: f32, + end_angle: f32, +) { + path.as_mut().ellipse( + center.to_rust(), + axes.to_rust(), + rotation, + start_angle, + end_angle, + ) } #[no_mangle] @@ -690,7 +790,10 @@ pub unsafe extern "C" fn PFPathClosePath(mut path: PFPathRef) { } #[no_mangle] -pub unsafe extern "C" fn PFFillStyleInitColor(fill_style: PFFillStyleRef, color: PFColorU) -> PFResult { +pub unsafe extern "C" fn PFFillStyleInitColor( + fill_style: PFFillStyleRef, + color: PFColorU, +) -> PFResult { fill_style.write(FillStyle::Color(color.to_rust())); PF_OK } @@ -710,14 +813,19 @@ pub unsafe extern "C" fn PFEmbeddedResourceLoaderInit(loader: PFResourceLoaderRe } #[no_mangle] -pub unsafe extern "C" fn PFFilesystemResourceLoaderLocateInit(loader: PFResourceLoaderRef) -> PFResult { +pub unsafe extern "C" fn PFFilesystemResourceLoaderLocateInit( + loader: PFResourceLoaderRef, +) -> PFResult { let inner = Box::new(FilesystemResourceLoader::locate()); loader.write(PFResourceLoader(inner as Box)); PF_OK } #[no_mangle] -pub unsafe extern "C" fn PFFilesystemResourceLoaderFromPathInit(loader: PFResourceLoaderRef, path: *const c_char) -> PFResult { +pub unsafe extern "C" fn PFFilesystemResourceLoaderFromPathInit( + loader: PFResourceLoaderRef, + path: *const c_char, +) -> PFResult { let string = to_rust_string(&path, 0); let directory = PathBuf::from(string); let inner = Box::new(FilesystemResourceLoader { directory }); @@ -741,11 +849,15 @@ pub unsafe extern "C" fn PFGLLoadWith(loader: PFGLFunctionLoader, userdata: *mut } #[no_mangle] -pub unsafe extern "C" fn PFGLDeviceInit(device: PFGLDeviceRef, version: PFGLVersion, default_framebuffer: u32) -> PFResult { +pub unsafe extern "C" fn PFGLDeviceInit( + device: PFGLDeviceRef, + version: PFGLVersion, + default_framebuffer: u32, +) -> PFResult { let version = match version { - PF_GL_VERSION_GL3 => GLVersion::GL3, + PF_GL_VERSION_GL3 => GLVersion::GL3, PF_GL_VERSION_GLES3 => GLVersion::GLES3, - PF_GL_VERSION_GL4 => GLVersion::GL4, + PF_GL_VERSION_GL4 => GLVersion::GL4, _ => { log::error!("Invalid Pathfinder OpenGL version: {}", version); return PFResult(1); @@ -763,7 +875,10 @@ pub unsafe extern "C" fn PFGLDeviceDeinit(device: PFGLDeviceRef) { // `gpu` #[no_mangle] -pub unsafe extern "C" fn PFGLDestFramebufferInitFullWindow(dest_framebuffer: PFGLDestFramebufferRef, window_size: PFVector2I) -> PFResult { +pub unsafe extern "C" fn PFGLDestFramebufferInitFullWindow( + dest_framebuffer: PFGLDestFramebufferRef, + window_size: PFVector2I, +) -> PFResult { dest_framebuffer.write(DestFramebuffer::full_window(window_size.to_rust())); PF_OK } @@ -776,20 +891,23 @@ pub unsafe extern "C" fn PFGLDestFramebufferDeinit(dest_framebuffer: PFGLDestFra /// This function does not take ownership of `resources`; therefore, if you /// created the resource loader, you must destroy it yourself to avoid a memory leak. #[no_mangle] -pub unsafe extern "C" fn PFGLRendererInit(renderer: PFGLRendererRef, - device: PFGLDeviceRef, - resources: PFResourceLoaderRef, - mode: PFRendererMode, - options: NonNull>) - -> PFResult { +pub unsafe extern "C" fn PFGLRendererInit( + renderer: PFGLRendererRef, + device: PFGLDeviceRef, + resources: PFResourceLoaderRef, + mode: PFRendererMode, + options: NonNull>, +) -> PFResult { let mode = match RendererMode::try_from(mode) { Ok(t) => t, Err(e) => return e, }; - renderer.write(Renderer::new(device.read(), - &*(resources.as_ref().0), - mode, - options.read().into_rust())); + renderer.write(Renderer::new( + device.read(), + &*(resources.as_ref().0), + mode, + options.read().into_rust(), + )); PF_OK } @@ -804,9 +922,14 @@ pub unsafe extern "C" fn PFGLRendererGetDevice(mut renderer: PFGLRendererRef) -> } #[no_mangle] -pub unsafe extern "C" fn PFGLRendererSetViewport(mut renderer: PFGLRendererRef, new_viewport: PFRectI) -> PFResult { +pub unsafe extern "C" fn PFGLRendererSetViewport( + mut renderer: PFGLRendererRef, + new_viewport: PFRectI, +) -> PFResult { match renderer.as_mut().options_mut().dest { - DestFramebuffer::Default { ref mut viewport, .. } => { + DestFramebuffer::Default { + ref mut viewport, .. + } => { *viewport = new_viewport.to_rust(); PF_OK } @@ -815,9 +938,15 @@ pub unsafe extern "C" fn PFGLRendererSetViewport(mut renderer: PFGLRendererRef, } #[no_mangle] -pub unsafe extern "C" fn PFGLRendererSetWindowSize(mut renderer: PFGLRendererRef, new_window_size: PFVector2I) -> PFResult { +pub unsafe extern "C" fn PFGLRendererSetWindowSize( + mut renderer: PFGLRendererRef, + new_window_size: PFVector2I, +) -> PFResult { match renderer.as_mut().options_mut().dest { - DestFramebuffer::Default { ref mut window_size, .. } => { + DestFramebuffer::Default { + ref mut window_size, + .. + } => { *window_size = new_window_size.to_rust(); PF_OK } @@ -832,7 +961,10 @@ pub unsafe extern "C" fn PFGLRendererDestFramebufferSizeChanged(mut renderer: PF #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub unsafe extern "C" fn PFMetalDestFramebufferInitFullWindow(dest_framebuffer: PFMetalDestFramebufferRef, window_size: PFVector2I) -> PFResult { +pub unsafe extern "C" fn PFMetalDestFramebufferInitFullWindow( + dest_framebuffer: PFMetalDestFramebufferRef, + window_size: PFVector2I, +) -> PFResult { dest_framebuffer.write(DestFramebuffer::full_window(window_size.to_rust())); PF_OK } @@ -848,20 +980,23 @@ pub unsafe extern "C" fn PFMetalDestFramebufferDeinit(dest_framebuffer: PFMetalD /// created the resource loader, you must destroy it yourself to avoid a memory leak. #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub unsafe extern "C" fn PFMetalRendererInit(renderer: PFMetalRendererRef, - device: PFMetalDeviceRef, - resources: PFResourceLoaderRef, - mode: PFRendererMode, - options: NonNull>) - -> PFResult { +pub unsafe extern "C" fn PFMetalRendererInit( + renderer: PFMetalRendererRef, + device: PFMetalDeviceRef, + resources: PFResourceLoaderRef, + mode: PFRendererMode, + options: NonNull>, +) -> PFResult { let mode = match RendererMode::try_from(mode) { Ok(t) => t, Err(e) => return e, }; - renderer.write(Renderer::new(device.read(), - &*(resources.as_ref().0), - mode, - options.into_rust())); + renderer.write(Renderer::new( + device.read(), + &*(resources.as_ref().0), + mode, + options.into_rust(), + )); PF_OK } @@ -876,69 +1011,87 @@ pub unsafe extern "C" fn PFMetalRendererDeinit(renderer: PFMetalRendererRef) { /// This reference remains valid as long as the device is alive. #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub unsafe extern "C" fn PFMetalRendererGetDevice(mut renderer: PFMetalRendererRef) -> PFMetalDeviceRef { +pub unsafe extern "C" fn PFMetalRendererGetDevice( + mut renderer: PFMetalRendererRef, +) -> PFMetalDeviceRef { renderer.as_mut().device_mut().into() } /// This function does not take ownership of `renderer`. Therefore, if you /// created the renderer and/or options, you must destroy them yourself to avoid a leak. #[no_mangle] -pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL(mut scene_proxy: PFSceneProxyRef, - mut renderer: PFGLRendererRef, - build_options: PFBuildOptionsRef) { - scene_proxy.as_mut().build_and_render(renderer.as_mut(), build_options.read()) +pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL( + mut scene_proxy: PFSceneProxyRef, + mut renderer: PFGLRendererRef, + build_options: PFBuildOptionsRef, +) { + scene_proxy + .as_mut() + .build_and_render(renderer.as_mut(), build_options.read()) } /// This function does not take ownership of `renderer`. Therefore, if you /// created the renderer and/or options, you must destroy them yourself to avoid a leak. #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub unsafe extern "C" fn PFSceneProxyBuildAndRenderMetal(mut scene_proxy: PFSceneProxyRef, - mut renderer: PFMetalRendererRef, - build_options: PFBuildOptionsRef) { - scene_proxy.as_mut().build_and_render(renderer.as_mut(), build_options.read()) +pub unsafe extern "C" fn PFSceneProxyBuildAndRenderMetal( + mut scene_proxy: PFSceneProxyRef, + mut renderer: PFMetalRendererRef, + build_options: PFBuildOptionsRef, +) { + scene_proxy + .as_mut() + .build_and_render(renderer.as_mut(), build_options.read()) } // `metal` #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub unsafe extern "C" fn PFMetalDeviceInitWithIOSurface(device: PFMetalDeviceRef, - metal_device: &NativeMetalDeviceRef, - io_surface: IOSurfaceRef) - -> PFResult { +pub unsafe extern "C" fn PFMetalDeviceInitWithIOSurface( + device: PFMetalDeviceRef, + metal_device: &NativeMetalDeviceRef, + io_surface: IOSurfaceRef, +) -> PFResult { device.write(MetalDevice::new(metal_device, io_surface)); PF_OK } #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub unsafe extern "C" fn PFMetalDeviceInitWithDrawable(device: PFMetalDeviceRef, - metal_device: &NativeMetalDeviceRef, - ca_drawable: &CoreAnimationDrawableRef) - -> PFResult { +pub unsafe extern "C" fn PFMetalDeviceInitWithDrawable( + device: PFMetalDeviceRef, + metal_device: &NativeMetalDeviceRef, + ca_drawable: &CoreAnimationDrawableRef, +) -> PFResult { device.write(MetalDevice::new(metal_device, ca_drawable)); PF_OK } #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub unsafe extern "C" fn PFMetalDeviceSwapIOSurface(mut device: PFMetalDeviceRef, - new_io_surface: IOSurfaceRef) { +pub unsafe extern "C" fn PFMetalDeviceSwapIOSurface( + mut device: PFMetalDeviceRef, + new_io_surface: IOSurfaceRef, +) { drop(device.as_mut().swap_texture(new_io_surface)) } #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub unsafe extern "C" fn PFMetalDeviceSwapDrawable(mut device: PFMetalDeviceRef, - new_ca_drawable: &CoreAnimationDrawableRef) { +pub unsafe extern "C" fn PFMetalDeviceSwapDrawable( + mut device: PFMetalDeviceRef, + new_ca_drawable: &CoreAnimationDrawableRef, +) { drop(device.as_mut().swap_texture(new_ca_drawable)) } #[cfg(all(target_os = "macos", feature = "metal"))] #[no_mangle] -pub unsafe extern "C" fn PFMetalDevicePresentDrawable(mut device: PFMetalDeviceRef, - ca_drawable: &CoreAnimationDrawableRef) { +pub unsafe extern "C" fn PFMetalDevicePresentDrawable( + mut device: PFMetalDeviceRef, + ca_drawable: &CoreAnimationDrawableRef, +) { device.as_mut().present_drawable(ca_drawable) } @@ -951,13 +1104,19 @@ pub unsafe extern "C" fn PFMetalDeviceDeinit(device: PFMetalDeviceRef) { // `renderer` #[no_mangle] -pub unsafe extern "C" fn PFRenderTransformInit2D(transform_dst: PFRenderTransformRef, transform: PFTransform2F) -> PFResult { +pub unsafe extern "C" fn PFRenderTransformInit2D( + transform_dst: PFRenderTransformRef, + transform: PFTransform2F, +) -> PFResult { transform_dst.write(RenderTransform::Transform2D(transform.to_rust())); PF_OK } #[no_mangle] -pub unsafe extern "C" fn PFRenderTransformInitPerspective(transform_dst: PFRenderTransformRef, perspective: PFPerspective) -> PFResult { +pub unsafe extern "C" fn PFRenderTransformInitPerspective( + transform_dst: PFRenderTransformRef, + perspective: PFPerspective, +) -> PFResult { transform_dst.write(RenderTransform::Perspective(perspective.to_rust())); PF_OK } @@ -974,8 +1133,10 @@ pub unsafe extern "C" fn PFBuildOptionsInit(options: PFBuildOptionsRef) -> PFRes } #[no_mangle] -pub unsafe extern "C" fn PFBuildOptionsSetDilation(mut options: PFBuildOptionsRef, - dilation: PFVector2F) { +pub unsafe extern "C" fn PFBuildOptionsSetDilation( + mut options: PFBuildOptionsRef, + dilation: PFVector2F, +) { options.as_mut().dilation = dilation.to_rust() } @@ -985,7 +1146,10 @@ pub unsafe extern "C" fn PFSceneDeinit(scene: PFSceneRef) { } #[no_mangle] -pub unsafe extern "C" fn PFSceneProxyInitWithSequentialExecutor(scene_proxy: PFSceneProxyRef, level: PFRendererLevel) -> PFResult { +pub unsafe extern "C" fn PFSceneProxyInitWithSequentialExecutor( + scene_proxy: PFSceneProxyRef, + level: PFRendererLevel, +) -> PFResult { let level = match to_rust_renderer_level(level) { Ok(t) => t, Err(e) => return e, @@ -995,7 +1159,10 @@ pub unsafe extern "C" fn PFSceneProxyInitWithSequentialExecutor(scene_proxy: PFS } #[no_mangle] -pub unsafe extern "C" fn PFSceneProxyInitWithRayonExecutor(scene_proxy: PFSceneProxyRef, level: PFRendererLevel) -> PFResult { +pub unsafe extern "C" fn PFSceneProxyInitWithRayonExecutor( + scene_proxy: PFSceneProxyRef, + level: PFRendererLevel, +) -> PFResult { let level = match to_rust_renderer_level(level) { Ok(t) => t, Err(e) => return e, @@ -1005,7 +1172,10 @@ pub unsafe extern "C" fn PFSceneProxyInitWithRayonExecutor(scene_proxy: PFSceneP } #[no_mangle] -pub unsafe extern "C" fn PFSceneProxyReplaceScene(mut scene_proxy: PFSceneProxyRef, scene: PFSceneRef) { +pub unsafe extern "C" fn PFSceneProxyReplaceScene( + mut scene_proxy: PFSceneProxyRef, + scene: PFSceneRef, +) { scene_proxy.as_mut().replace_scene(scene.read()) } @@ -1016,8 +1186,13 @@ pub unsafe extern "C" fn PFSceneProxyDeinit(scene_proxy: PFSceneProxyRef) { // `svg` +#[cfg(feature = "svg")] #[no_mangle] -pub unsafe extern "C" fn PFSVGSceneInitWithMemory(svg_scene: PFSVGSceneRef, bytes: *const c_char, byte_len: usize) -> PFResult { +pub unsafe extern "C" fn PFSVGSceneInitWithMemory( + svg_scene: PFSVGSceneRef, + bytes: *const c_char, + byte_len: usize, +) -> PFResult { let data = slice::from_raw_parts(bytes as *const _, byte_len); let tree = match Tree::from_data(data, &Options::default()) { Ok(tree) => tree, @@ -1027,8 +1202,12 @@ pub unsafe extern "C" fn PFSVGSceneInitWithMemory(svg_scene: PFSVGSceneRef, byte PF_OK } +#[cfg(feature = "svg")] #[no_mangle] -pub unsafe extern "C" fn PFSVGSceneInitWithPath(svg_scene: PFSVGSceneRef, path: *const c_char) -> PFResult { +pub unsafe extern "C" fn PFSVGSceneInitWithPath( + svg_scene: PFSVGSceneRef, + path: *const c_char, +) -> PFResult { let string = to_rust_string(&path, 0); let path = PathBuf::from(string); let tree = match Tree::from_file(path, &Options::default()) { @@ -1040,13 +1219,125 @@ pub unsafe extern "C" fn PFSVGSceneInitWithPath(svg_scene: PFSVGSceneRef, path: } /// Deinitializes the SVG and returns the scene. +#[cfg(feature = "svg")] #[no_mangle] -pub unsafe extern "C" fn PFSVGSceneIntoScene(svg: PFSVGSceneRef, scene_dst: PFSceneRef) -> PFResult { +pub unsafe extern "C" fn PFSVGSceneIntoScene( + svg: PFSVGSceneRef, + scene_dst: PFSceneRef, +) -> PFResult { let svg = svg.read(); scene_dst.write(svg.scene); PF_OK } +// `font-kit` + +#[no_mangle] +pub unsafe extern "C" fn FKFontDeinit(font: FKFontRef) { + font.drop_in_place(); +} + +#[no_mangle] +pub unsafe extern "C" fn FKFontMetrics(font: &FKFont) -> FKMetrics { + let Metrics { units_per_em, ascent, descent, line_gap, underline_position, underline_thickness, cap_height, x_height, bounding_box } = font.metrics(); + FKMetrics { units_per_em, ascent, descent, line_gap, underline_position, underline_thickness, cap_height, x_height, bounding_box: PFRectF::from(bounding_box) } +} + +/// The high 32 bits of the return value will be a boolean value indicating whether the glyph was +/// found, and the low 32 bits will be the glyph value, if it was found. +/// +/// # Safety +/// +/// `codepoint` must be a valid Unicode codepoint. +#[no_mangle] +pub unsafe extern "C" fn FKFontGlyphForCodepoint(font: &FKFont, codepoint: u32) -> u64 { + let c = char::from_u32_unchecked(codepoint); + let Some(id) = font.glyph_for_char(c) else { + return 0; + }; + (1u64 << 32) | id as u64 +} + +#[no_mangle] +pub extern "C" fn FKFontRasterBounds( + font: &FKFont, + glyph_id: u32, + point_size: f32, + rasterization_options: FKCanvasRasterizationOptions, + dst: &mut MaybeUninit, +) -> PFResult { + match font.raster_bounds( + glyph_id, + point_size, + Transform2F::default(), + font_kit::hinting::HintingOptions::None, + rasterization_options, + ) { + Ok(rect) => { + dst.write(PFRectI { + origin: PFVector2I { + x: rect.origin().x(), + y: rect.origin().y(), + }, + lower_right: PFVector2I { + x: rect.lower_right().x(), + y: rect.lower_right().y(), + }, + }); + PF_OK + } + Err(e) => { + log::error!("Failed to rasterize glyph: {e}"); + PFResult(1) + } + } +} + +#[no_mangle] +pub extern "C" fn FKFontRasterizeGlyph( + font: &FKFont, + canvas_pixels: NonNull, + canvas_pixels_len: usize, + canvas_size: PFVector2I, + canvas_format: FKCanvasFormat, + glyph_id: u32, + point_size: f32, + //transform: PFTransform2F, + translation: PFVector2F, + rasterization_options: FKCanvasRasterizationOptions, +) -> PFResult { + let canvas_size = canvas_size.to_rust(); + let translation = translation.to_rust(); + let mut canvas = font_kit::canvas::Canvas { + pixels: unsafe { NonNull::slice_from_raw_parts(canvas_pixels, canvas_pixels_len).as_mut() }, + size: canvas_size, + format: canvas_format, + }; + let transform = Transform2F::from_translation(translation); + //let metrics = font.metrics(); + //let bb = metrics.bounding_box * (point_size / metrics.units_per_em as f32); + //let bb = RectF::new(Vector2F::new(-bb.origin().x(), canvas_size.y() as f32 + bb.origin().y() + bb.size().y()), Vector2F::new(bb.size().x(), bb.size().y())); + //let bb = RectF::new(Vector2F::new(-bb.origin().x(), canvas_size.y() as f32 + bb.origin().y() + bb.size().y()), Vector2F::new(bb.size().x(), bb.size().y())); + //let transform = Transform2F::from_translation(canvas_size.to_f32() - raster_rect.size().to_f32() - raster_rect.origin().to_f32()); + //let transform = Transform2F::from_translation(bb.origin()); + //let transform = Transform2F::from_translation(raster_rect.size().to_f32()); + //let transform = Transform2F::default(); + match font.rasterize_glyph( + &mut canvas, + glyph_id, + point_size, + transform, + font_kit::hinting::HintingOptions::None, + rasterization_options, + ) { + Ok(()) => PF_OK, + Err(e) => { + log::error!("Failed to rasterize glyph: {e}"); + PFResult(1) + } + } +} + // Helpers for `canvas` unsafe fn to_rust_string(ptr: &*const c_char, mut len: usize) -> &str { @@ -1062,7 +1353,9 @@ trait TextMetricsExt { impl TextMetricsExt for TextMetrics { fn to_c(&self) -> PFTextMetrics { - PFTextMetrics { width: self.width() } + PFTextMetrics { + width: self.width(), + } } } @@ -1078,7 +1371,12 @@ impl PFColorF { impl PFColorU { #[inline] pub fn to_rust(&self) -> ColorU { - ColorU { r: self.r, g: self.g, b: self.b, a: self.a } + ColorU { + r: self.r, + g: self.g, + b: self.b, + a: self.a, + } } } @@ -1091,6 +1389,15 @@ impl PFRectF { } } +impl From for PFRectF { + fn from(value: RectF) -> Self { + Self { + origin: value.origin().into(), + lower_right: value.lower_right().into(), + } + } +} + impl PFRectI { #[inline] pub fn to_rust(&self) -> RectI { @@ -1105,6 +1412,12 @@ impl PFVector2F { } } +impl From for PFVector2F { + fn from(value: Vector2F) -> Self { + Self { x: value.x(), y: value.y() } + } +} + impl PFVector2I { #[inline] pub fn to_rust(&self) -> Vector2I { @@ -1122,17 +1435,20 @@ impl PFMatrix2x2F { impl PFTransform2F { #[inline] pub fn to_rust(&self) -> Transform2F { - Transform2F { matrix: self.matrix.to_rust(), vector: self.vector.to_rust() } + Transform2F { + matrix: self.matrix.to_rust(), + vector: self.vector.to_rust(), + } } } impl PFTransform4F { #[inline] pub fn to_rust(&self) -> Transform4F { - Transform4F::row_major(self.m00, self.m01, self.m02, self.m03, - self.m10, self.m11, self.m12, self.m13, - self.m20, self.m21, self.m22, self.m23, - self.m30, self.m31, self.m32, self.m33) + Transform4F::row_major( + self.m00, self.m01, self.m02, self.m03, self.m10, self.m11, self.m12, self.m13, + self.m20, self.m21, self.m22, self.m23, self.m30, self.m31, self.m32, self.m33, + ) } } @@ -1179,9 +1495,9 @@ impl PFRendererOptions { #[inline] fn to_rust_renderer_level(level: PFRendererLevel) -> Result { match level { - PF_RENDERER_LEVEL_D3D9 => Ok(RendererLevel::D3D9), + PF_RENDERER_LEVEL_D3D9 => Ok(RendererLevel::D3D9), PF_RENDERER_LEVEL_D3D11 => Ok(RendererLevel::D3D11), - _ => { + _ => { log::error!("Invalid Pathfinder renderer level: {}", level); Err(PFResult(1)) } diff --git a/canvas/Cargo.toml b/canvas/Cargo.toml index e3aef620..21209a93 100644 --- a/canvas/Cargo.toml +++ b/canvas/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["pathfinder", "canvas", "vector", "graphics", "gpu"] crate-type = ["rlib", "staticlib"] [dependencies] -font-kit = { version = "0.6", optional = true } +font-kit = { version = "0.13", optional = true } [dependencies.pathfinder_color] path = "../color" diff --git a/canvas/src/lib.rs b/canvas/src/lib.rs index 1c3c3a30..5e2e8b0d 100644 --- a/canvas/src/lib.rs +++ b/canvas/src/lib.rs @@ -10,14 +10,14 @@ //! 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_color::{rgbaf, rgbau, rgbf, rgbu, ColorF, ColorU}; pub use pathfinder_content::fill::FillRule; -pub use pathfinder_content::stroke::LineCap; pub use pathfinder_content::outline::ArcDirection; +pub use pathfinder_content::stroke::LineCap; pub use pathfinder_geometry::rect::{RectF, RectI}; pub use pathfinder_geometry::transform2d::Transform2F; -pub use pathfinder_geometry::vector::{IntoVector2F, Vector2F, Vector2I, vec2f, vec2i}; +pub use pathfinder_geometry::vector::{vec2f, vec2i, IntoVector2F, Vector2F, Vector2I}; use pathfinder_content::dash::OutlineDash; use pathfinder_content::effects::{BlendMode, BlurDirection, PatternFilter}; @@ -25,25 +25,25 @@ use pathfinder_content::gradient::Gradient; use pathfinder_content::outline::{Contour, Outline}; use pathfinder_content::pattern::{Image, Pattern}; use pathfinder_content::render_target::RenderTargetId; -use pathfinder_content::stroke::{LineJoin as StrokeLineJoin}; +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::f32::consts::PI; 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")] +use skribo::FontCollection; #[cfg(feature = "pf-text")] pub use text::TextMetrics; @@ -108,11 +108,16 @@ impl Canvas { self.scene } - pub fn get_context_2d(self, canvas_font_context: CanvasFontContext) - -> CanvasRenderingContext2D { + 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(); + 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 { @@ -131,7 +136,8 @@ impl Canvas { /// This resets the canvas' bounds. Do not call this mid-draw. pub fn set_size(&mut self, new_size: Vector2F) { self.scene.set_bounds(RectF::default()); - self.scene.set_view_box(RectF::new(Vector2F::zero(), new_size)); + self.scene + .set_view_box(RectF::new(Vector2F::zero(), new_size)); } } @@ -272,12 +278,18 @@ impl CanvasRenderingContext2D { // Fill and stroke styles #[inline] - pub fn set_fill_style(&mut self, new_fill_style: FS) where FS: Into { + 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 { + 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(); } @@ -336,9 +348,11 @@ impl CanvasRenderingContext2D { 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); + let mut dash = OutlineDash::new( + &outline, + &self.current_state.line_dash, + self.current_state.line_dash_offset, + ); dash.dash(); outline = dash.into_outline(); } @@ -373,23 +387,29 @@ impl CanvasRenderingContext2D { 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(); + 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)); + 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()); + 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())); + 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 @@ -412,9 +432,11 @@ impl CanvasRenderingContext2D { path.set_blend_mode(blend_mode); self.canvas.scene.push_draw_path(path); - composite_shadow_blur_render_targets_if_needed(&mut self.canvas.scene, - shadow_blur_info, - clip_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); @@ -423,10 +445,11 @@ impl CanvasRenderingContext2D { path.set_blend_mode(blend_mode); self.canvas.scene.push_draw_path(path); - fn push_shadow_blur_render_targets_if_needed(scene: &mut Scene, - current_state: &State, - outline_bounds: RectF) - -> Option { + 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; } @@ -447,9 +470,11 @@ impl CanvasRenderingContext2D { }) } - fn composite_shadow_blur_render_targets_if_needed(scene: &mut Scene, - info: Option, - clip_path: Option) { + 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, @@ -460,15 +485,21 @@ impl CanvasRenderingContext2D { 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 })); + 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 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); @@ -479,7 +510,6 @@ impl CanvasRenderingContext2D { scene.pop_render_target(); scene.push_draw_path(path_y); } - } // Transformations @@ -490,7 +520,10 @@ impl CanvasRenderingContext2D { } #[inline] - pub fn scale(&mut self, scale: S) where S: IntoVector2F { + pub fn scale(&mut self, scale: S) + where + S: IntoVector2F, + { self.current_state.transform *= Transform2F::from_scale(scale) } @@ -540,14 +573,20 @@ impl CanvasRenderingContext2D { #[inline] pub fn draw_image(&mut self, image: I, dest_location: L) - where I: CanvasImageSource, L: CanvasImageDestLocation { + 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 { + 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() * scale; @@ -563,7 +602,9 @@ impl CanvasRenderingContext2D { // Pixel manipulation pub fn put_image_data(&mut self, image_data: ImageData, dest_location: L) - where L: CanvasImageDestLocation { + where + L: CanvasImageDestLocation, + { let origin = dest_location.origin(); let size = dest_location.size().unwrap_or(image_data.size.to_f32()); let pattern = Pattern::from_image(image_data.into_image()); @@ -610,8 +651,11 @@ impl CanvasRenderingContext2D { // Extensions - pub fn create_pattern_from_canvas(&mut self, canvas: Canvas, transform: Transform2F) - -> Pattern { + 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()); @@ -724,7 +768,10 @@ pub struct Path2D { impl Path2D { #[inline] pub fn new() -> Path2D { - Path2D { outline: Outline::new(), current_contour: Contour::new() } + Path2D { + outline: Outline::new(), + current_contour: Contour::new(), + } } #[inline] @@ -754,14 +801,17 @@ impl Path2D { } #[inline] - pub fn arc(&mut self, - center: Vector2F, - radius: f32, - start_angle: f32, - end_angle: f32, - direction: ArcDirection) { + 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); + self.current_contour + .push_arc(&transform, start_angle, end_angle, direction); } #[inline] @@ -775,10 +825,11 @@ impl Path2D { 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)); + 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); + self.current_contour + .push_arc_from_unit_chord(&transform, chord, ArcDirection::CW); } pub fn rect(&mut self, rect: RectF) { @@ -790,17 +841,23 @@ impl Path2D { self.current_contour.close(); } - pub fn ellipse(&mut self, - center: Vector2F, - axes: A, - rotation: f32, - start_angle: f32, - end_angle: f32) - where A: IntoVector2F { + 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); + 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(); @@ -826,7 +883,8 @@ impl Path2D { fn flush_current_contour(&mut self) { if !self.current_contour.is_empty() { - self.outline.push_contour(mem::replace(&mut self.current_contour, Contour::new())); + self.outline + .push_contour(mem::replace(&mut self.current_contour, Contour::new())); } } } @@ -948,8 +1006,11 @@ pub enum ImageSmoothingQuality { } pub trait CanvasImageSource { - fn to_pattern(self, dest_context: &mut CanvasRenderingContext2D, transform: Transform2F) - -> Pattern; + fn to_pattern( + self, + dest_context: &mut CanvasRenderingContext2D, + transform: Transform2F, + ) -> Pattern; } pub trait CanvasImageDestLocation { @@ -967,8 +1028,11 @@ impl CanvasImageSource for Pattern { impl CanvasImageSource for Canvas { #[inline] - fn to_pattern(self, dest_context: &mut CanvasRenderingContext2D, transform: Transform2F) - -> Pattern { + fn to_pattern( + self, + dest_context: &mut CanvasRenderingContext2D, + transform: Transform2F, + ) -> Pattern { dest_context.create_pattern_from_canvas(self, transform) } } @@ -1003,7 +1067,10 @@ pub struct ImageData { impl ImageData { #[inline] pub fn new(size: Vector2I) -> ImageData { - ImageData { data: vec![ColorU::transparent_black(); size.area() as usize], size } + ImageData { + data: vec![ColorU::transparent_black(); size.area() as usize], + size, + } } #[inline] diff --git a/canvas/src/tests.rs b/canvas/src/tests.rs index 6aad4818..bcb5dbe5 100644 --- a/canvas/src/tests.rs +++ b/canvas/src/tests.rs @@ -3,8 +3,8 @@ // 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; +use pathfinder_geometry::vector::{vec2f, Vector2F}; #[test] pub fn test_path2d_formatting() { diff --git a/canvas/src/text.rs b/canvas/src/text.rs index 1ba2b36d..e5dd8436 100644 --- a/canvas/src/text.rs +++ b/canvas/src/text.rs @@ -10,7 +10,7 @@ use crate::{CanvasRenderingContext2D, State, TextAlign, TextBaseline}; use font_kit::canvas::RasterizationOptions; -use font_kit::error::{GlyphLoadingError, FontLoadingError, SelectionError}; +use font_kit::error::{FontLoadingError, GlyphLoadingError, SelectionError}; use font_kit::family_name::FamilyName; use font_kit::handle::Handle; use font_kit::hinting::HintingOptions; @@ -20,7 +20,7 @@ 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_geometry::vector::{vec2f, Vector2F}; use pathfinder_renderer::paint::PaintId; use pathfinder_text::{FontContext, FontRenderOptions, TextRenderMode}; use skribo::{FontCollection, FontFamily, FontRef, Layout as SkriboLayout, TextStyle}; @@ -36,8 +36,13 @@ impl CanvasRenderingContext2D { /// fill the text that you passed into `measure_text()` with the layout-related style /// properties set at the time you called that function. This allows Pathfinder to skip having /// to lay out the text again. - pub fn fill_text(&mut self, text: &T, position: Vector2F) -> Result<(), GlyphLoadingError> where T: ToTextLayout + ?Sized { - let paint = self.current_state.resolve_paint(&self.current_state.fill_paint); + pub fn fill_text(&mut self, text: &T, position: Vector2F) -> Result<(), GlyphLoadingError> + where + T: ToTextLayout + ?Sized, + { + 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(text, position, paint_id, TextRenderMode::Fill) } @@ -48,8 +53,13 @@ impl CanvasRenderingContext2D { /// stroke the text that you passed into `measure_text()` with the layout-related style /// properties set at the time you called that function. This allows Pathfinder to skip having /// to lay out the text again. - pub fn stroke_text(&mut self, text: &T, position: Vector2F) -> Result<(), GlyphLoadingError> where T: ToTextLayout + ?Sized { - let paint = self.current_state.resolve_paint(&self.current_state.stroke_paint); + pub fn stroke_text(&mut self, text: &T, position: Vector2F) -> Result<(), GlyphLoadingError> + where + T: ToTextLayout + ?Sized, + { + 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(text, position, paint_id, render_mode) @@ -60,39 +70,53 @@ impl CanvasRenderingContext2D { /// As an extension, the returned `TextMetrics` object contains all the layout data for the /// string and can be used in its place when calling `fill_text()` and `stroke_text()` to avoid /// needlessly performing layout multiple times. - pub fn measure_text(&self, text: &T) -> TextMetrics where T: ToTextLayout + ?Sized { + pub fn measure_text(&self, text: &T) -> TextMetrics + where + T: ToTextLayout + ?Sized, + { text.layout(CanvasState(&self.current_state)).into_owned() } - fn fill_or_stroke_text(&mut self, - text: &T, - mut position: Vector2F, - paint_id: PaintId, - render_mode: TextRenderMode) -> Result<(), GlyphLoadingError> - where T: ToTextLayout + ?Sized { + fn fill_or_stroke_text( + &mut self, + text: &T, + mut position: Vector2F, + paint_id: PaintId, + render_mode: TextRenderMode, + ) -> Result<(), GlyphLoadingError> + where + T: ToTextLayout + ?Sized, + { let layout = text.layout(CanvasState(&self.current_state)); let clip_path = self.current_state.clip_path; - let blend_mode = self.current_state.global_composite_operation.to_blend_mode(); + let blend_mode = self + .current_state + .global_composite_operation + .to_blend_mode(); position += layout.text_origin(); let transform = self.current_state.transform * Transform2F::from_translation(position); self.canvas_font_context - .0 - .borrow_mut() - .font_context - .push_layout(&mut self.canvas.scene, - &layout.skribo_layout, - &TextStyle { size: layout.font_size }, - &FontRenderOptions { - transform, - render_mode, - hinting_options: HintingOptions::None, - clip_path, - blend_mode, - paint_id, - })?; + .0 + .borrow_mut() + .font_context + .push_layout( + &mut self.canvas.scene, + &layout.skribo_layout, + &TextStyle { + size: layout.font_size, + }, + &FontRenderOptions { + transform, + render_mode, + hinting_options: HintingOptions::None, + clip_path, + blend_mode, + paint_id, + }, + )?; Ok(()) } @@ -105,9 +129,12 @@ impl CanvasRenderingContext2D { } #[inline] - pub fn set_font(&mut self, font_collection: FC) -> Result<(), FontError> where FC: IntoFontCollection { + pub fn set_font(&mut self, font_collection: FC) -> Result<(), FontError> + where + FC: IntoFontCollection, + { let font_collection = font_collection.into_font_collection(&self.canvas_font_context)?; - self.current_state.font_collection = font_collection; + self.current_state.font_collection = font_collection; Ok(()) } @@ -155,7 +182,13 @@ pub trait ToTextLayout { impl ToTextLayout for str { fn layout(&self, state: CanvasState) -> Cow { - Cow::Owned(TextMetrics::layout(self, &state.0.font_collection, state.0.font_size, state.0.text_align, state.0.text_baseline)) + Cow::Owned(TextMetrics::layout( + self, + &state.0.font_collection, + state.0.font_size, + state.0.text_align, + state.0.text_baseline, + )) } } @@ -168,10 +201,12 @@ impl ToTextLayout for String { impl ToTextLayout for Rc { fn layout(&self, state: CanvasState) -> Cow { - Cow::Owned(TextMetrics::new((*self).clone(), - state.0.font_size, - state.0.text_align, - state.0.text_baseline)) + Cow::Owned(TextMetrics::new( + (*self).clone(), + state.0.font_size, + state.0.text_align, + state.0.text_baseline, + )) } } @@ -203,8 +238,9 @@ pub(super) struct CanvasFontContextData { 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) = + 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)); } @@ -224,7 +260,10 @@ impl CanvasFontContext { } /// 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 { + pub fn from_fonts(fonts: I) -> CanvasFontContext + where + I: Iterator, + { CanvasFontContext::new(Arc::new(MemSource::from_fonts(fonts).unwrap())) } @@ -236,7 +275,8 @@ impl CanvasFontContext { this.font_source .select_by_postscript_name(postscript_name) .map_err(FontError::NotFound)? - .load().map_err(FontError::LoadError) + .load() + .map_err(FontError::LoadError) } } @@ -298,11 +338,12 @@ struct VerticalMetrics { } impl TextMetrics { - pub fn new(skribo_layout: Rc, - font_size: f32, - align: TextAlign, - baseline: TextBaseline) - -> TextMetrics { + pub fn new( + skribo_layout: Rc, + font_size: f32, + align: TextAlign, + baseline: TextBaseline, + ) -> TextMetrics { TextMetrics { skribo_layout, font_size, @@ -317,10 +358,18 @@ impl TextMetrics { } } - pub fn layout(string: &str, font_collection: &FontCollection, font_size: f32, text_align: TextAlign, text_baseline: TextBaseline) -> TextMetrics { - let skribo_layout = Rc::new(skribo::layout(&TextStyle { size: font_size }, - font_collection, - string)); + pub fn layout( + string: &str, + font_collection: &FontCollection, + font_size: f32, + text_align: TextAlign, + text_baseline: TextBaseline, + ) -> TextMetrics { + let skribo_layout = Rc::new(skribo::layout( + &TextStyle { size: font_size }, + font_collection, + string, + )); TextMetrics::new(skribo_layout, font_size, text_align, text_baseline) } @@ -342,11 +391,11 @@ impl TextMetrics { self.text_y_offset.set(Some(match self.baseline { TextBaseline::Alphabetic => 0.0, TextBaseline::Top => vertical_metrics.em_height_ascent, - TextBaseline::Middle => { - util::lerp(vertical_metrics.em_height_ascent, - vertical_metrics.em_height_descent, - 0.5) - } + TextBaseline::Middle => util::lerp( + vertical_metrics.em_height_ascent, + vertical_metrics.em_height_descent, + 0.5, + ), TextBaseline::Bottom => vertical_metrics.em_height_descent, TextBaseline::Ideographic => vertical_metrics.ideographic_baseline, TextBaseline::Hanging => vertical_metrics.hanging_baseline, @@ -368,39 +417,56 @@ impl TextMetrics { let font_metrics = last_glyph.font.font.metrics(); let scale_factor = self.skribo_layout.size / font_metrics.units_per_em as f32; let glyph_rect = last_glyph.font.font.typographic_bounds(glyph_id).unwrap(); - self.width.set(Some(last_glyph.offset.x() + - glyph_rect.max_x() * scale_factor)); + self.width.set(Some( + last_glyph.offset.x() + glyph_rect.max_x() * scale_factor, + )); } } - } self.width.get().unwrap() } fn populate_vertical_metrics_if_necessary(&self) { if self.vertical_metrics.get().is_none() { - self.vertical_metrics.set(Some(VerticalMetrics::measure(&self.skribo_layout))); + self.vertical_metrics + .set(Some(VerticalMetrics::measure(&self.skribo_layout))); } } pub fn font_bounding_box_ascent(&self) -> f32 { self.populate_vertical_metrics_if_necessary(); - self.vertical_metrics.get().unwrap().font_bounding_box_ascent - self.text_y_offset() + self.vertical_metrics + .get() + .unwrap() + .font_bounding_box_ascent + - self.text_y_offset() } pub fn font_bounding_box_descent(&self) -> f32 { self.populate_vertical_metrics_if_necessary(); - self.vertical_metrics.get().unwrap().font_bounding_box_descent - self.text_y_offset() + self.vertical_metrics + .get() + .unwrap() + .font_bounding_box_descent + - self.text_y_offset() } pub fn actual_bounding_box_ascent(&self) -> f32 { self.populate_vertical_metrics_if_necessary(); - self.vertical_metrics.get().unwrap().actual_bounding_box_ascent - self.text_y_offset() + self.vertical_metrics + .get() + .unwrap() + .actual_bounding_box_ascent + - self.text_y_offset() } pub fn actual_bounding_box_descent(&self) -> f32 { self.populate_vertical_metrics_if_necessary(); - self.vertical_metrics.get().unwrap().actual_bounding_box_descent - self.text_y_offset() + self.vertical_metrics + .get() + .unwrap() + .actual_bounding_box_descent + - self.text_y_offset() } pub fn em_height_ascent(&self) -> f32 { @@ -421,14 +487,20 @@ impl TextMetrics { let glyph_id = first_glyph.glyph_id; let font_metrics = first_glyph.font.font.metrics(); let scale_factor = self.skribo_layout.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(); - self.actual_left_extent.set(Some(first_glyph.offset.x() + - glyph_rect.min_x() as f32 * scale_factor)); + 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(); + self.actual_left_extent.set(Some( + first_glyph.offset.x() + glyph_rect.min_x() as f32 * scale_factor, + )); } } } @@ -443,14 +515,20 @@ impl TextMetrics { let glyph_id = last_glyph.glyph_id; let font_metrics = last_glyph.font.font.metrics(); let scale_factor = self.skribo_layout.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(); - self.actual_right_extent.set(Some(last_glyph.offset.x() + - glyph_rect.max_x() as f32 * scale_factor)); + 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(); + self.actual_right_extent.set(Some( + last_glyph.offset.x() + glyph_rect.max_x() as f32 * scale_factor, + )); } } } @@ -471,7 +549,6 @@ impl TextMetrics { self.populate_vertical_metrics_if_necessary(); self.vertical_metrics.get().unwrap().ideographic_baseline - self.text_y_offset() } - } impl VerticalMetrics { @@ -498,28 +575,30 @@ impl VerticalMetrics { let font_metrics = font.metrics(); let scale_factor = skribo_layout.size / font_metrics.units_per_em as f32; vertical_metrics.em_height_ascent = - (font_metrics.ascent * - scale_factor).max(vertical_metrics.em_height_ascent); - vertical_metrics.em_height_descent = - (font_metrics.descent * - scale_factor).min(vertical_metrics.em_height_descent); - vertical_metrics.font_bounding_box_ascent = - (font_metrics.bounding_box.max_y() * - scale_factor).max(vertical_metrics.font_bounding_box_ascent); + (font_metrics.ascent * scale_factor).max(vertical_metrics.em_height_ascent); + vertical_metrics.em_height_descent = (font_metrics.descent * scale_factor) + .min(vertical_metrics.em_height_descent); + vertical_metrics.font_bounding_box_ascent = (font_metrics.bounding_box.max_y() + * scale_factor) + .max(vertical_metrics.font_bounding_box_ascent); vertical_metrics.font_bounding_box_descent = - (font_metrics.bounding_box.min_y() * - scale_factor).min(vertical_metrics.font_bounding_box_descent); + (font_metrics.bounding_box.min_y() * scale_factor) + .min(vertical_metrics.font_bounding_box_descent); last_font = Some(font); } } let font = last_font.as_ref().unwrap(); - let glyph_rect = font.raster_bounds(glyph.glyph_id, - skribo_layout.size, - Transform2F::default(), - HintingOptions::None, - RasterizationOptions::GrayscaleAa).unwrap(); + let glyph_rect = font + .raster_bounds( + glyph.glyph_id, + skribo_layout.size, + Transform2F::default(), + HintingOptions::None, + RasterizationOptions::GrayscaleAa, + ) + .unwrap(); vertical_metrics.actual_bounding_box_ascent = (glyph_rect.max_y() as f32).max(vertical_metrics.actual_bounding_box_ascent); vertical_metrics.actual_bounding_box_descent = @@ -533,7 +612,10 @@ impl VerticalMetrics { /// 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) -> Result, FontError>; + fn into_font_collection( + self, + font_context: &CanvasFontContext, + ) -> Result, FontError>; } impl IntoFontCollection for Arc { @@ -565,14 +647,20 @@ impl IntoFontCollection for Vec { impl IntoFontCollection for Font { #[inline] - fn into_font_collection(self, context: &CanvasFontContext) -> Result, FontError> { + fn into_font_collection( + self, + context: &CanvasFontContext, + ) -> Result, FontError> { Ok(FontFamily::new_from_font(self).into_font_collection(context)?) } } impl<'a> IntoFontCollection for &'a [Font] { #[inline] - fn into_font_collection(self, context: &CanvasFontContext) -> Result, FontError> { + fn into_font_collection( + self, + context: &CanvasFontContext, + ) -> Result, FontError> { let mut family = FontFamily::new(); for font in self { family.add_font(FontRef::new((*font).clone())) @@ -583,14 +671,22 @@ impl<'a> IntoFontCollection for &'a [Font] { impl<'a> IntoFontCollection for &'a str { #[inline] - fn into_font_collection(self, context: &CanvasFontContext) -> Result, FontError> { - context.get_font_by_postscript_name(self)?.into_font_collection(context) + fn into_font_collection( + self, + context: &CanvasFontContext, + ) -> Result, FontError> { + 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) -> Result, FontError> { + fn into_font_collection( + self, + context: &CanvasFontContext, + ) -> Result, FontError> { let mut font_collection = FontCollection::new(); for postscript_name in self { let font = context.get_font_by_postscript_name(postscript_name)?; diff --git a/color/src/lib.rs b/color/src/lib.rs index a104f644..b03d2595 100644 --- a/color/src/lib.rs +++ b/color/src/lib.rs @@ -127,13 +127,13 @@ impl ColorF { 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(), + 1 => xc.yxzw(), + 2 => xc.xyzw(), + 3 => xc.zyxw(), + 4 => xc.zxyw(), + 5 => xc.xzyw(), 0 | 6 => xc.yzxw(), - _ => xc.zzzw(), + _ => xc.zzzw(), }; let m = l - 0.5 * c; ColorF(rgba + F32x4::new(m, m, m, 0.0)) @@ -162,7 +162,12 @@ impl ColorF { #[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 } + ColorU { + r: color[0] as u8, + g: color[1] as u8, + b: color[2] as u8, + a: color[3] as u8, + } } #[inline] @@ -226,9 +231,7 @@ impl Debug for ColorF { #[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) - } + unsafe { slice::from_raw_parts(slice.as_ptr() as *const u8, slice.len() * 4) } } #[inline] diff --git a/color/src/matrix.rs b/color/src/matrix.rs index ed5d197a..5fa71d16 100644 --- a/color/src/matrix.rs +++ b/color/src/matrix.rs @@ -9,7 +9,7 @@ // except according to those terms. use pathfinder_simd::default::F32x4; -use std::ops::{Add, Mul, Deref}; +use std::ops::{Add, Deref, Mul}; /// ColorMatrix filter/transformation /// @@ -34,22 +34,22 @@ impl ColorMatrix { /// See the `hueRotate` attribute of the `feColorMatrix` element in the SVG specification. pub fn hue_rotate(angle: f32) -> ColorMatrix { let a = ColorMatrix::from_rows([ - [ 0.213, 0.715, 0.072, 0.0, 0.0], - [ 0.213, 0.715, 0.072, 0.0, 0.0], - [ 0.213, 0.715, 0.072, 0.0, 0.0], - [ 0.0, 0.0, 0.0, 1.0, 0.0], + [0.213, 0.715, 0.072, 0.0, 0.0], + [0.213, 0.715, 0.072, 0.0, 0.0], + [0.213, 0.715, 0.072, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], ]); let b = ColorMatrix::from_rows([ - [ 0.787, -0.715, -0.072, 0.0, 0.0], - [-0.213, 0.285, -0.072, 0.0, 0.0], - [-0.213, -0.715, 0.928, 0.0, 0.0], - [ 0.0, 0.0, 0.0, 0.0, 0.0], + [0.787, -0.715, -0.072, 0.0, 0.0], + [-0.213, 0.285, -0.072, 0.0, 0.0], + [-0.213, -0.715, 0.928, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], ]); let c = ColorMatrix::from_rows([ - [-0.213, -0.715, 0.928, 0.0, 0.0], - [ 0.143, 0.140, -0.283, 0.0, 0.0], - [-0.787, 0.715, 0.072, 0.0, 0.0], - [ 0.0, 0.0, 0.0, 0.0, 0.0], + [-0.213, -0.715, 0.928, 0.0, 0.0], + [0.143, 0.140, -0.283, 0.0, 0.0], + [-0.787, 0.715, 0.072, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], ]); a + b * angle.cos() + c * angle.sin() } @@ -59,16 +59,16 @@ impl ColorMatrix { /// See the `saturate` attribute of the `feColorMatrix` element in the SVG specification. pub fn saturate(saturation: f32) -> ColorMatrix { let a = ColorMatrix::from_rows([ - [ 0.213, 0.715, 0.072, 0.0, 0.0], - [ 0.213, 0.715, 0.072, 0.0, 0.0], - [ 0.213, 0.715, 0.072, 0.0, 0.0], - [ 0.0, 0.0, 0.0, 1.0, 0.0], + [0.213, 0.715, 0.072, 0.0, 0.0], + [0.213, 0.715, 0.072, 0.0, 0.0], + [0.213, 0.715, 0.072, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], ]); let b = ColorMatrix::from_rows([ - [ 0.787, -0.715, -0.072, 0.0, 0.0], - [-0.213, 0.285, -0.072, 0.0, 0.0], - [-0.213, -0.715, 0.928, 0.0, 0.0], - [ 0.0, 0.0, 0.0, 0.0, 0.0], + [0.787, -0.715, -0.072, 0.0, 0.0], + [-0.213, 0.285, -0.072, 0.0, 0.0], + [-0.213, -0.715, 0.928, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], ]); a + b * saturation } @@ -79,10 +79,10 @@ impl ColorMatrix { /// specification. pub fn luminance_to_alpha() -> ColorMatrix { ColorMatrix::from_rows([ - [ 0.0, 0.0, 0.0, 0.0, 0.0], - [ 0.0, 0.0, 0.0, 0.0, 0.0], - [ 0.0, 0.0, 0.0, 0.0, 0.0], - [ 0.2125, 0.7154, 0.0721, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.2125, 0.7154, 0.0721, 0.0, 0.0], ]) } } diff --git a/content/src/clip.rs b/content/src/clip.rs index 08d09274..d60f04b5 100644 --- a/content/src/clip.rs +++ b/content/src/clip.rs @@ -18,7 +18,7 @@ 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, vec2f}; +use pathfinder_geometry::vector::{vec2f, Vector2F, Vector4F}; use smallvec::SmallVec; use std::fmt::Debug; use std::mem; @@ -491,8 +491,10 @@ pub(crate) fn rect_is_inside_polygon(rect: RectF, polygon_points: &[Vector2F]) - } /// Clips a line segment to an axis-aligned rectangle using Cohen-Sutherland clipping. -pub fn clip_line_segment_to_rect(mut line_segment: LineSegment2F, rect: RectF) - -> Option { +pub fn clip_line_segment_to_rect( + mut line_segment: LineSegment2F, + rect: RectF, +) -> Option { let mut outcode_from = compute_outcode(line_segment.from(), rect); let mut outcode_to = compute_outcode(line_segment.to(), rect); @@ -512,29 +514,45 @@ pub fn clip_line_segment_to_rect(mut line_segment: LineSegment2F, rect: RectF) }; if outcode.contains(Outcode::LEFT) { - point = vec2f(rect.min_x(), - lerp(line_segment.from_y(), - line_segment.to_y(), - (rect.min_x() - line_segment.from_x()) / - (line_segment.to_x() - line_segment.from_x()))); + point = vec2f( + rect.min_x(), + lerp( + line_segment.from_y(), + line_segment.to_y(), + (rect.min_x() - line_segment.from_x()) + / (line_segment.to_x() - line_segment.from_x()), + ), + ); } else if outcode.contains(Outcode::RIGHT) { - point = vec2f(rect.max_x(), - lerp(line_segment.from_y(), - line_segment.to_y(), - (rect.max_x() - line_segment.from_x()) / - (line_segment.to_x() - line_segment.from_x()))); + point = vec2f( + rect.max_x(), + lerp( + line_segment.from_y(), + line_segment.to_y(), + (rect.max_x() - line_segment.from_x()) + / (line_segment.to_x() - line_segment.from_x()), + ), + ); } else if outcode.contains(Outcode::TOP) { - point = vec2f(lerp(line_segment.from_x(), - line_segment.to_x(), - (rect.min_y() - line_segment.from_y()) / - (line_segment.to_y() - line_segment.from_y())), - rect.min_y()); + point = vec2f( + lerp( + line_segment.from_x(), + line_segment.to_x(), + (rect.min_y() - line_segment.from_y()) + / (line_segment.to_y() - line_segment.from_y()), + ), + rect.min_y(), + ); } else if outcode.contains(Outcode::BOTTOM) { - point = vec2f(lerp(line_segment.from_x(), - line_segment.to_x(), - (rect.max_y() - line_segment.from_y()) / - (line_segment.to_y() - line_segment.from_y())), - rect.max_y()); + point = vec2f( + lerp( + line_segment.from_x(), + line_segment.to_x(), + (rect.max_y() - line_segment.from_y()) + / (line_segment.to_y() - line_segment.from_y()), + ), + rect.max_y(), + ); } if clip_from { diff --git a/content/src/dash.rs b/content/src/dash.rs index 35ff3fd5..e7b0d464 100644 --- a/content/src/dash.rs +++ b/content/src/dash.rs @@ -38,7 +38,11 @@ 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) } + OutlineDash { + input, + output: Outline::new(), + state: DashState::new(dashes, offset), + } } /// Performs the dashing operation. @@ -66,9 +70,16 @@ struct ContourDash<'a, 'b, 'c> { } 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 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) { @@ -95,13 +106,16 @@ impl<'a, 'b, 'c> ContourDash<'a, 'b, 'c> { } if self.state.is_on() { - self.state.output.push_segment(¤t_segment, PushSegmentFlags::empty()); + 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.output + .push_contour(mem::replace(&mut self.state.output, Contour::new())); } self.state.current_dash_index += 1; diff --git a/content/src/dilation.rs b/content/src/dilation.rs index 9e39f699..f86e2031 100644 --- a/content/src/dilation.rs +++ b/content/src/dilation.rs @@ -10,7 +10,7 @@ use crate::orientation::Orientation; use crate::outline::Contour; -use pathfinder_geometry::vector::{Vector2F, vec2f}; +use pathfinder_geometry::vector::{vec2f, Vector2F}; pub struct ContourDilator<'a> { contour: &'a mut Contour, @@ -33,10 +33,11 @@ impl<'a> ContourDilator<'a> { 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), - }); + 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); diff --git a/content/src/effects.rs b/content/src/effects.rs index c2933f85..af9dc7ee 100644 --- a/content/src/effects.rs +++ b/content/src/effects.rs @@ -10,7 +10,7 @@ //! Special effects that can be applied to layers. -use pathfinder_color::{ColorF, matrix::ColorMatrix}; +use pathfinder_color::{matrix::ColorMatrix, ColorF}; use pathfinder_geometry::line_segment::LineSegment2F; use pathfinder_geometry::vector::Vector2F; use pathfinder_simd::default::F32x2; @@ -88,7 +88,7 @@ pub enum PatternFilter { }, /// A color matrix multiplication. - /// + /// /// The matrix is stored in 5 columns of `F32x4`. See the `feColorMatrix` element in the SVG /// specification. ColorMatrix(ColorMatrix), @@ -202,64 +202,64 @@ impl BlendMode { 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, + 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, + 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/content/src/gradient.rs b/content/src/gradient.rs index bab52c5d..9ca5365d 100644 --- a/content/src/gradient.rs +++ b/content/src/gradient.rs @@ -14,8 +14,8 @@ 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_geometry::vector::Vector2F; use pathfinder_simd::default::F32x2; use std::cmp::Ordering; use std::convert; @@ -67,7 +67,7 @@ pub enum GradientGeometry { /// Like `gradientTransform` in SVG. Note that this is the inverse of Cairo's gradient /// transform. transform: Transform2F, - } + }, } /// What should be rendered outside the color stops. @@ -83,13 +83,20 @@ pub enum GradientWrap { impl Eq for Gradient {} impl Hash for Gradient { - fn hash(&self, state: &mut H) where H: Hasher { + 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 } => { + GradientGeometry::Radial { + line, + radii, + transform, + } => { (1).hash(state); util::hash_line_segment(line, state); util::hash_f32(radii.x(), state); @@ -109,7 +116,10 @@ impl Hash for Gradient { impl Eq for ColorStop {} impl Hash for ColorStop { - fn hash(&self, state: &mut H) where H: Hasher { + fn hash(&self, state: &mut H) + where + H: Hasher, + { unsafe { self.color.hash(state); let offset = mem::transmute::(self.offset); @@ -145,10 +155,17 @@ impl Gradient { /// with two circles, pass a `LineSegment2F`. To start the gradient at the center of the /// circle, pass zero for the first radius. #[inline] - pub fn radial(line: L, radii: F32x2) -> Gradient where L: RadialGradientLine { + 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 }, + geometry: GradientGeometry::Radial { + line: line.to_line(), + radii, + transform, + }, stops: Vec::new(), wrap: GradientWrap::Clamp, } @@ -157,9 +174,16 @@ impl Gradient { /// Adds a new color stop to the radial gradient. #[inline] pub fn add(&mut self, stop: ColorStop) { - let index = self.stops.binary_search_by(|other| { - if other.offset <= stop.offset { Ordering::Less } else { Ordering::Greater } - }).unwrap_or_else(convert::identity); + let index = self + .stops + .binary_search_by(|other| { + if other.offset <= stop.offset { + Ordering::Less + } else { + Ordering::Greater + } + }) + .unwrap_or_else(convert::identity); self.stops.insert(index, stop); } @@ -193,10 +217,22 @@ impl Gradient { 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| { - if stop.offset < t || stop.offset == 0.0 { Ordering::Less } else { Ordering::Greater } - }).unwrap_or_else(convert::identity).min(last_index); - let lower_index = if upper_index > 0 { upper_index - 1 } else { upper_index }; + let upper_index = self + .stops + .binary_search_by(|stop| { + if stop.offset < t || stop.offset == 0.0 { + Ordering::Less + } else { + Ordering::Greater + } + }) + .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[lower_index]; let upper_stop = &self.stops[upper_index]; @@ -207,7 +243,11 @@ impl Gradient { } let ratio = ((t - lower_stop.offset) / denom).min(1.0); - lower_stop.color.to_f32().lerp(upper_stop.color.to_f32(), ratio).to_u8() + lower_stop + .color + .to_f32() + .lerp(upper_stop.color.to_f32(), ratio) + .to_u8() } /// Returns true if all colors of all stops in this gradient are opaque (alpha is 1.0). @@ -220,7 +260,9 @@ impl Gradient { /// 0.0). #[inline] pub fn is_fully_transparent(&self) -> bool { - self.stops.iter().all(|stop| stop.color.is_fully_transparent()) + self.stops + .iter() + .all(|stop| stop.color.is_fully_transparent()) } /// Applies the given affine transform to this gradient. @@ -234,9 +276,9 @@ impl Gradient { match self.geometry { GradientGeometry::Linear(ref mut line) => *line = new_transform * *line, - GradientGeometry::Radial { ref mut transform, .. } => { - *transform = new_transform * *transform - } + GradientGeometry::Radial { + ref mut transform, .. + } => *transform = new_transform * *transform, } } } @@ -283,9 +325,10 @@ mod test { } // Check that it sorted stably - assert!(grad.stops.windows(2).all(|w| { - w[0].offset < w[1].offset || w[0].color.r < w[1].color.r - })); + assert!(grad + .stops + .windows(2) + .all(|w| { w[0].offset < w[1].offset || w[0].color.r < w[1].color.r })); } #[test] @@ -293,7 +336,10 @@ mod test { let mut grad = Gradient::linear_from_points(Vector2F::default(), Vector2F::default()); for i in 0..110 { let zero_width = (i == 0) || (11 <= i && i < 99) || (i == 109); - grad.add_color_stop(ColorU::new(if zero_width { 255 } else { 0 }, 0, 0, 1), (i % 11) as f32 / 10.0); + grad.add_color_stop( + ColorU::new(if zero_width { 255 } else { 0 }, 0, 0, 1), + (i % 11) as f32 / 10.0, + ); } for i in 0..11 { diff --git a/content/src/outline.rs b/content/src/outline.rs index c86086a7..ce3036cb 100644 --- a/content/src/outline.rs +++ b/content/src/outline.rs @@ -17,10 +17,10 @@ use crate::segment::{Segment, SegmentFlags, SegmentKind}; use crate::util::safe_sqrt; use pathfinder_geometry::line_segment::LineSegment2F; use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::transform2d::{Transform2F, Matrix2x2F}; +use pathfinder_geometry::transform2d::{Matrix2x2F, Transform2F}; use pathfinder_geometry::transform3d::Perspective; use pathfinder_geometry::unit_vector::UnitVector; -use pathfinder_geometry::vector::{Vector2F, vec2f}; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use std::f32::consts::PI; use std::fmt::{self, Debug, Formatter}; use std::mem; @@ -90,7 +90,10 @@ impl Outline { /// Creates a new outline from a list of segments. #[inline] - pub fn from_segments(segments: I) -> Outline where I: Iterator { + pub fn from_segments(segments: I) -> Outline + where + I: Iterator, + { let mut outline = Outline::new(); let mut current_contour = Contour::new(); @@ -380,7 +383,7 @@ impl Contour { contour.push_cubic( vec2f(p0.x(), p1.y()), vec2f(p1.x(), p0.y()), - vec2f(p2.x(), p0.y()) + vec2f(p2.x(), p0.y()), ); } @@ -393,7 +396,7 @@ impl Contour { contour.push_cubic( vec2f(p1.x(), p0.y()), vec2f(p0.x(), p1.y()), - vec2f(p0.x(), p2.y()) + vec2f(p0.x(), p2.y()), ); } @@ -406,7 +409,7 @@ impl Contour { contour.push_cubic( vec2f(p0.x(), p1.y()), vec2f(p1.x(), p0.y()), - vec2f(p2.x(), p0.y()) + vec2f(p2.x(), p0.y()), ); } @@ -419,7 +422,7 @@ impl Contour { contour.push_cubic( vec2f(p1.x(), p0.y()), vec2f(p0.x(), p1.y()), - vec2f(p0.x(), p2.y()) + vec2f(p0.x(), p2.y()), ); } @@ -557,10 +560,7 @@ impl Contour { } #[inline] - pub(crate) fn push_point(&mut self, - point: Vector2F, - flags: PointFlags, - update_bounds: bool) { + 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 { @@ -612,26 +612,30 @@ impl Contour { /// /// * `direction`: Whether the arc should be drawn clockwise or counterclockwise from the +x /// axis. - pub fn push_arc(&mut self, - transform: &Transform2F, - start_angle: f32, - end_angle: f32, - direction: ArcDirection) { + 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()); + let end = vec2f(end_angle.cos(), end_angle.sin()); self.push_arc_from_unit_chord(transform, LineSegment2F::new(start, end), direction); } } /// Given the endpoints of a unit arc, adds Bézier curves to approximate that arc to the /// current contour. The given transform is applied to the resulting arc. - pub fn push_arc_from_unit_chord(&mut self, - transform: &Transform2F, - mut chord: LineSegment2F, - direction: ArcDirection) { + 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); @@ -640,15 +644,17 @@ impl Contour { 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); + 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); + debug!( + "... end_vector={:?} vector={:?} sweep_vector={:?} last={:?}", + end_vector, vector, sweep_vector, last + ); let mut segment; if !last { @@ -683,12 +689,14 @@ impl Contour { /// Draws an ellipse section with radii given by `radius` rotated by `x_axis_rotation` in /// radians to `to` in the given direction. If `large_arc` is true, draws an arc bigger than /// π radians, otherwise smaller than π radians. - pub fn push_svg_arc(&mut self, - radius: Vector2F, - x_axis_rotation: f32, - large_arc: bool, - direction: ArcDirection, - to: Vector2F) { + pub fn push_svg_arc( + &mut self, + radius: Vector2F, + x_axis_rotation: f32, + large_arc: bool, + direction: ArcDirection, + to: Vector2F, + ) { let r = radius; let p = to; let last = self.last_position().unwrap_or_default(); @@ -698,7 +706,7 @@ impl Contour { let r_inv = r.recip(); let sign = match (large_arc, direction) { (false, ArcDirection::CW) | (true, ArcDirection::CCW) => 1.0, - (false, ArcDirection::CCW) | (true, ArcDirection::CW) => -1.0 + (false, ArcDirection::CCW) | (true, ArcDirection::CW) => -1.0, }; let rot = Matrix2x2F::from_rotation(x_axis_rotation); // x' @@ -716,10 +724,14 @@ impl Contour { let rq2 = r2 * q2.yx(); // (r_x^2 q_y^2, r_y^2 q_x^2) let rq2_sum = rq2.x() + rq2.y(); // r_x^2 q_y^2 + r_y^2 q_x^2 - // c' - let s = vec2f(1., -1.) * r * (q * r_inv).yx() * safe_sqrt((r2_prod - rq2_sum) / rq2_sum) * sign; + // c' + let s = vec2f(1., -1.) + * r + * (q * r_inv).yx() + * safe_sqrt((r2_prod - rq2_sum) / rq2_sum) + * sign; let c = rot * s + (last + p) * 0.5; - + let a = (q - s) * r_inv; let b = -(q + s) * r_inv; (a, b, c) @@ -729,10 +741,10 @@ impl Contour { let b = -a; (a, b, c) }; - + let transform = Transform2F { matrix: rot, - vector: c + vector: c, } * Transform2F::from_scale(r); let chord = LineSegment2F::new(a, b); self.push_arc_from_unit_chord(&transform, chord, direction); @@ -747,17 +759,25 @@ impl Contour { 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); + 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, + ); } /// Returns the segment starting at the point with the given index. @@ -812,7 +832,7 @@ impl Contour { #[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) + .intersects(PointFlags::CONTROL_POINT_0 | PointFlags::CONTROL_POINT_1) } /// Returns `point_index + addend` modulo the number of points in this contour. @@ -928,8 +948,10 @@ impl Contour { impl Debug for Contour { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - for (segment_index, segment) in self.iter(ContourIterFlags::IGNORE_CLOSE_SEGMENT) - .enumerate() { + for (segment_index, segment) in self + .iter(ContourIterFlags::IGNORE_CLOSE_SEGMENT) + .enumerate() + { if segment_index == 0 { write!( formatter, @@ -1024,10 +1046,11 @@ impl<'a> Iterator for ContourIter<'a> { 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 { + 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; } @@ -1050,7 +1073,10 @@ impl<'a> Iterator for ContourIter<'a> { 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)); + return Some(Segment::quadratic( + LineSegment2F::new(point0, point2), + point1, + )); } let point3_index = self.index; diff --git a/content/src/pattern.rs b/content/src/pattern.rs index c69ade84..7724e996 100644 --- a/content/src/pattern.rs +++ b/content/src/pattern.rs @@ -15,7 +15,7 @@ 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 pathfinder_geometry::vector::{vec2i, Vector2I}; use std::collections::hash_map::DefaultHasher; use std::fmt::{self, Debug, Formatter}; use std::hash::{Hash, Hasher}; @@ -46,7 +46,7 @@ pub enum PatternSource { id: RenderTargetId, /// The device pixel size of the render target. size: Vector2I, - } + }, } /// A raster image, in 32-bit RGBA (8 bits per channel), non-premultiplied form. @@ -213,7 +213,12 @@ impl Image { pixels.hash(&mut pixels_hasher); let pixels_hash = pixels_hasher.finish(); - Image { size, pixels, pixels_hash, is_opaque } + Image { + size, + pixels, + pixels_hash, + is_opaque, + } } /// A convenience function to create a new image with the given image from the `image` crate. @@ -280,7 +285,10 @@ impl Debug for Image { } impl Hash for Image { - fn hash(&self, hasher: &mut H) where H: Hasher { + fn hash(&self, hasher: &mut H) + where + H: Hasher, + { self.size.hash(hasher); self.pixels_hash.hash(hasher); self.is_opaque.hash(hasher); @@ -290,7 +298,10 @@ impl Hash for Image { impl Eq for Pattern {} impl Hash for Pattern { - fn hash(&self, state: &mut H) where H: Hasher { + 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/content/src/segment.rs b/content/src/segment.rs index ed2cbd9f..c597d3ab 100644 --- a/content/src/segment.rs +++ b/content/src/segment.rs @@ -13,7 +13,7 @@ use pathfinder_geometry::line_segment::LineSegment2F; use pathfinder_geometry::transform2d::Transform2F; use pathfinder_geometry::util::EPSILON; -use pathfinder_geometry::vector::{Vector2F, vec2f}; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use pathfinder_simd::default::F32x4; use std::f32::consts::SQRT_2; @@ -100,8 +100,12 @@ impl Segment { 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 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()); @@ -175,8 +179,9 @@ impl Segment { 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.ctrl = + LineSegment2F::new(self.baseline.from() + p1_2, p1_2 + self.baseline.to()) + * (1.0 / 3.0); new_segment.kind = SegmentKind::Cubic; new_segment } diff --git a/content/src/stroke.rs b/content/src/stroke.rs index 8ea20349..2c275b23 100644 --- a/content/src/stroke.rs +++ b/content/src/stroke.rs @@ -16,15 +16,15 @@ 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 pathfinder_geometry::vector::{vec2f, Vector2F}; use std::f32; const TOLERANCE: f32 = 0.01; /// Strokes an outline with a stroke style to produce a new outline. -/// +/// /// An example of use: -/// +/// /// ```no_run /// use pathfinder_content::stroke::OutlineStrokeToFill; /// use pathfinder_content::stroke::StrokeStyle; @@ -86,7 +86,11 @@ impl<'a> OutlineStrokeToFill<'a> { /// given stroke style. #[inline] pub fn new(input: &Outline, style: StrokeStyle) -> OutlineStrokeToFill { - OutlineStrokeToFill { input, output: Outline::new(), style } + OutlineStrokeToFill { + input, + output: Outline::new(), + style, + } } /// Performs the stroke operation. @@ -94,18 +98,22 @@ impl<'a> OutlineStrokeToFill<'a> { 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); + 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); + stroker = ContourStrokeToFill::new( + input, + Contour::new(), + self.style.line_width * 0.5, + self.style.line_join, + ); } else { self.add_cap(&mut stroker.output); } @@ -119,7 +127,9 @@ impl<'a> OutlineStrokeToFill<'a> { } let mut new_bounds = None; - new_contours.iter().for_each(|contour| contour.update_bounds(&mut new_bounds)); + 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()); @@ -131,18 +141,22 @@ impl<'a> OutlineStrokeToFill<'a> { self.output } - fn push_stroked_contour(&mut self, - new_contours: &mut Vec, - mut stroker: ContourStrokeToFill, - closed: bool) { + 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.add_join( + self.style.line_width * 0.5, + self.style.line_join, + stroker.input.position_of(0), + final_segment, + ); } stroker.output.closed = true; @@ -151,7 +165,7 @@ impl<'a> OutlineStrokeToFill<'a> { fn add_cap(&mut self, contour: &mut Contour) { if self.style.line_cap == LineCap::Butt || contour.len() < 2 { - return + return; } let width = self.style.line_width; @@ -209,14 +223,23 @@ struct ContourStrokeToFill<'a> { impl<'a> ContourStrokeToFill<'a> { #[inline] fn new(input: &Contour, output: Contour, radius: f32, join: LineJoin) -> ContourStrokeToFill { - ContourStrokeToFill { input, output, radius, join } + 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 }; + let join = if segment_index == 0 { + LineJoin::Bevel + } else { + self.join + }; segment.offset(-self.radius, join, &mut self.output); } } @@ -231,7 +254,11 @@ impl<'a> ContourStrokeToFill<'a> { 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 }; + let join = if segment_index == 0 { + LineJoin::Bevel + } else { + self.join + }; segment.offset(-self.radius, join, &mut self.output); } } @@ -239,11 +266,13 @@ impl<'a> ContourStrokeToFill<'a> { 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 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; } @@ -270,11 +299,13 @@ impl Offset for Segment { after.offset(distance, join, contour); } - fn add_to_contour(&self, - distance: f32, - join: LineJoin, - join_point: Vector2F, - contour: &mut 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(); @@ -404,11 +435,13 @@ impl Contour { } } - fn add_join(&mut self, - distance: f32, - join: LineJoin, - join_point: Vector2F, - next_tangent: LineSegment2F) { + 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); @@ -456,10 +489,14 @@ impl Default for StrokeStyle { impl Default for LineCap { #[inline] - fn default() -> LineCap { LineCap::Butt } + fn default() -> LineCap { + LineCap::Butt + } } impl Default for LineJoin { #[inline] - fn default() -> LineJoin { LineJoin::Miter(10.0) } + fn default() -> LineJoin { + LineJoin::Miter(10.0) + } } diff --git a/content/src/transform.rs b/content/src/transform.rs index 8cdcbdf0..b753900f 100644 --- a/content/src/transform.rs +++ b/content/src/transform.rs @@ -36,8 +36,12 @@ where // 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()); + 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() { @@ -83,10 +87,16 @@ where 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()); + 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()); + segment + .ctrl + .set_from(self.perspective * segment.ctrl.from()); if !segment.is_quadratic() { segment.ctrl.set_to(self.perspective * segment.ctrl.to()); } diff --git a/content/src/util.rs b/content/src/util.rs index fc4808da..d8a84d3a 100644 --- a/content/src/util.rs +++ b/content/src/util.rs @@ -16,30 +16,45 @@ 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 { +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 { +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 { +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 { +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 { +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/demo/android/rust/src/lib.rs b/demo/android/rust/src/lib.rs index 2a129d7d..73bfb93f 100644 --- a/demo/android/rust/src/lib.rs +++ b/demo/android/rust/src/lib.rs @@ -16,8 +16,8 @@ use jni::{JNIEnv, JavaVM}; use pathfinder_demo::window::{Event, SVGPath, View, Window, WindowSize}; use pathfinder_demo::DemoApp; use pathfinder_demo::Options; -use pathfinder_geometry::vector::{Vector2I, vec2i}; use pathfinder_geometry::rect::RectI; +use pathfinder_geometry::vector::{vec2i, Vector2I}; use pathfinder_gl::GLVersion; use pathfinder_resources::ResourceLoader; use std::cell::RefCell; @@ -131,7 +131,10 @@ pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_Pathfinder x: i32, y: i32, ) { - EVENT_QUEUE.lock().unwrap().push(Event::MouseDown(vec2i(x, y))) + EVENT_QUEUE + .lock() + .unwrap() + .push(Event::MouseDown(vec2i(x, y))) } #[no_mangle] @@ -141,7 +144,10 @@ pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_Pathfinder x: i32, y: i32, ) { - EVENT_QUEUE.lock().unwrap().push(Event::MouseDragged(vec2i(x, y))) + EVENT_QUEUE + .lock() + .unwrap() + .push(Event::MouseDragged(vec2i(x, y))) } #[no_mangle] @@ -152,7 +158,10 @@ pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_Pathfinder center_x: i32, center_y: i32, ) { - EVENT_QUEUE.lock().unwrap().push(Event::Zoom(factor, vec2i(center_x, center_y))) + EVENT_QUEUE + .lock() + .unwrap() + .push(Event::Zoom(factor, vec2i(center_x, center_y))) } #[no_mangle] diff --git a/demo/common/Cargo.toml b/demo/common/Cargo.toml index db7c3510..27be90c7 100644 --- a/demo/common/Cargo.toml +++ b/demo/common/Cargo.toml @@ -11,7 +11,7 @@ pf-gl = [] clap = "2.32" gl = "0.14" rayon = "1.0" -usvg = "0.9" +usvg = "0.10" [dependencies.image] version = "0.23" diff --git a/demo/common/src/camera.rs b/demo/common/src/camera.rs index 35cf7619..0c79d4e7 100644 --- a/demo/common/src/camera.rs +++ b/demo/common/src/camera.rs @@ -14,10 +14,10 @@ // proper. use crate::window::{OcularTransform, View}; -use pathfinder_geometry::vector::{Vector2I, Vector4F}; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::transform2d::Transform2F; use pathfinder_geometry::transform3d::{Perspective, Transform4F}; +use pathfinder_geometry::vector::{Vector2I, Vector4F}; use std::f32::consts::FRAC_PI_4; const NEAR_CLIP_PLANE: f32 = 0.01; @@ -53,8 +53,8 @@ impl Camera { } fn new_2d(view_box: RectF, viewport_size: Vector2I) -> Camera { - let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 * - scale_factor_for_view_box(view_box); + let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 + * scale_factor_for_view_box(view_box); let origin = viewport_size.to_f32() * 0.5 - view_box.size() * (scale * 0.5); Camera::TwoD(Transform2F::from_scale(scale).translate(origin)) } @@ -154,9 +154,10 @@ impl CameraTransform3D { pub fn to_transform(&self) -> Transform4F { let flip = Vector4F::new(1.0, -1.0, 1.0, 1.0); - Transform4F::from_scale(flip).translate(-self.position) - .uniform_scale(2.0 * self.scale) - .rotate(self.yaw, self.pitch, 0.0) + Transform4F::from_scale(flip) + .translate(-self.position) + .uniform_scale(2.0 * self.scale) + .rotate(self.yaw, self.pitch, 0.0) } } diff --git a/demo/common/src/concurrent.rs b/demo/common/src/concurrent.rs index de8caf73..ba781427 100644 --- a/demo/common/src/concurrent.rs +++ b/demo/common/src/concurrent.rs @@ -35,7 +35,10 @@ impl DemoExecutor { impl Executor for DemoExecutor { fn build_vector(&self, length: usize, builder: F) -> Vec - where T: Send, F: Fn(usize) -> T + Send + Sync { + where + T: Send, + F: Fn(usize) -> T + Send + Sync, + { if self.sequential_mode { SequentialExecutor.build_vector(length, builder) } else { diff --git a/demo/common/src/device.rs b/demo/common/src/device.rs index f477b4b0..b84a8449 100644 --- a/demo/common/src/device.rs +++ b/demo/common/src/device.rs @@ -63,19 +63,33 @@ where ) -> GroundVertexArray { let vertex_array = device.create_vertex_array(); - let position_attr = device.get_vertex_attr(&ground_program.program, "Position").unwrap(); + let position_attr = device + .get_vertex_attr(&ground_program.program, "Position") + .unwrap(); - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + device.bind_buffer( + &vertex_array, + quad_vertex_positions_buffer, + BufferTarget::Vertex, + ); + device.configure_vertex_attr( + &vertex_array, + &position_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }, + ); + device.bind_buffer( + &vertex_array, + quad_vertex_indices_buffer, + BufferTarget::Index, + ); GroundVertexArray { vertex_array } } diff --git a/demo/common/src/lib.rs b/demo/common/src/lib.rs index 0ef437c0..4de58dcd 100644 --- a/demo/common/src/lib.rs +++ b/demo/common/src/lib.rs @@ -20,10 +20,10 @@ use crate::camera::Camera; use crate::concurrent::DemoExecutor; use crate::device::{GroundProgram, GroundVertexArray}; use crate::ui::{DemoUIModel, DemoUIPresenter, ScreenshotInfo, ScreenshotType, UIAction}; -use crate::window::{Event, Keycode, DataPath, Window, WindowSize}; +use crate::window::{DataPath, Event, Keycode, Window, WindowSize}; use clap::{App, Arg}; -use pathfinder_content::effects::DEFRINGING_KERNEL_CORE_GRAPHICS; use pathfinder_content::effects::PatternFilter; +use pathfinder_content::effects::DEFRINGING_KERNEL_CORE_GRAPHICS; use pathfinder_content::effects::STEM_DARKENING_FACTORS; use pathfinder_content::outline::Outline; use pathfinder_content::pattern::Pattern; @@ -32,7 +32,7 @@ use pathfinder_export::{Export, FileFormat}; use pathfinder_geometry::rect::{RectF, RectI}; use pathfinder_geometry::transform2d::Transform2F; use pathfinder_geometry::transform3d::Transform4F; -use pathfinder_geometry::vector::{Vector2F, Vector2I, Vector4F, vec2f, vec2i}; +use pathfinder_geometry::vector::{vec2f, vec2i, Vector2F, Vector2I, Vector4F}; use pathfinder_gpu::Device; use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererLevel}; @@ -44,14 +44,14 @@ use pathfinder_renderer::scene::{DrawPath, RenderTarget, Scene}; use pathfinder_resources::ResourceLoader; use pathfinder_svg::SVGScene; use pathfinder_ui::{MousePosition, UIEvent}; +use pdf::file::{CachedFile, FileOptions}; +use pdf_render::{Cache as PdfRenderCache, SceneBackend}; use std::fs::File; use std::io::BufWriter; use std::path::PathBuf; use std::thread; use std::time::Duration; use usvg::{Options as UsvgOptions, Tree as SvgTree}; -use pdf::file::{CachedFile, FileOptions}; -use pdf_render::{Cache as PdfRenderCache, SceneBackend}; #[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] use pathfinder_gl::GLDevice as DeviceImpl; @@ -88,11 +88,14 @@ enum Content { Pdf { file: CachedFile>, cache: PdfRenderCache, - page_nr: u32 - } + page_nr: u32, + }, } -pub struct DemoApp where W: Window { +pub struct DemoApp +where + W: Window, +{ pub window: W, pub should_exit: bool, pub options: Options, @@ -126,7 +129,10 @@ pub struct DemoApp where W: Window { ground_vertex_array: GroundVertexArray, } -impl DemoApp where W: Window { +impl DemoApp +where + W: Window, +{ pub fn new(window: W, window_size: WindowSize, options: Options) -> DemoApp { let expire_message_event_id = window.create_user_event_id(); @@ -172,17 +178,18 @@ impl DemoApp where W: Window { let renderer = Renderer::new(device, resources, render_mode, render_options); - let scene_metadata = SceneMetadata::new_clipping_view_box(&mut scene, - viewport.size()); + let scene_metadata = SceneMetadata::new_clipping_view_box(&mut scene, viewport.size()); let camera = Camera::new(options.mode, scene_metadata.view_box, viewport.size()); let scene_proxy = SceneProxy::from_scene(scene, level, executor); let ground_program = GroundProgram::new(renderer.device(), resources); - let ground_vertex_array = GroundVertexArray::new(renderer.device(), - &ground_program, - &renderer.quad_vertex_positions_buffer(), - &renderer.quad_vertex_indices_buffer()); + let ground_vertex_array = GroundVertexArray::new( + renderer.device(), + &ground_program, + &renderer.quad_vertex_positions_buffer(), + &renderer.quad_vertex_indices_buffer(), + ); let mut message_epoch = 0; emit_message::( @@ -260,9 +267,9 @@ impl DemoApp where W: Window { if modelview_transform.offset(*velocity) { self.dirty = true; } - let perspective = scene_transform.perspective * - scene_transform.modelview_to_eye * - modelview_transform.to_transform(); + let perspective = scene_transform.perspective + * scene_transform.modelview_to_eye + * modelview_transform.to_transform(); Some(RenderTransform::Perspective(perspective)) } Camera::TwoD(transform) => Some(RenderTransform::Transform2D(transform)), @@ -281,7 +288,7 @@ impl DemoApp where W: Window { self.scene_proxy.build(build_options); /* - self.render_command_stream = + self.render_command_stream = Some(self.scene_proxy.build_with_stream(build_options, self.renderer.gpu_features())); */ } @@ -299,8 +306,8 @@ impl DemoApp where W: Window { Event::WindowResized(new_size) => { self.window_size = new_size; let viewport = self.window.viewport(self.ui_model.mode.view(0)); - self.scene_proxy.set_view_box(RectF::new(Vector2F::zero(), - viewport.size().to_f32())); + self.scene_proxy + .set_view_box(RectF::new(Vector2F::zero(), viewport.size().to_f32())); self.renderer.options_mut().dest = DestFramebuffer::full_window(self.window_size.device_size()); self.renderer.dest_framebuffer_size_changed(); @@ -312,7 +319,11 @@ impl DemoApp where W: Window { } Event::MouseMoved(new_position) if self.mouselook_enabled => { let mouse_position = self.process_mouse_position(new_position); - if let Camera::ThreeD { ref mut modelview_transform, .. } = self.camera { + if let Camera::ThreeD { + ref mut modelview_transform, + .. + } = self.camera + { let rotation = mouse_position.relative.to_f32() * MOUSELOOK_ROTATION_SPEED; modelview_transform.yaw += rotation.x(); modelview_transform.pitch += rotation.y(); @@ -329,13 +340,18 @@ impl DemoApp where W: Window { let backing_scale_factor = self.window_size.backing_scale_factor; let position = position.to_f32() * backing_scale_factor; let scale_delta = 1.0 + d_dist * CAMERA_SCALE_SPEED_2D; - *transform = transform.translate(-position) - .scale(scale_delta) - .translate(position); + *transform = transform + .translate(-position) + .scale(scale_delta) + .translate(position); } } Event::Look { pitch, yaw } => { - if let Camera::ThreeD { ref mut modelview_transform, .. } = self.camera { + if let Camera::ThreeD { + ref mut modelview_transform, + .. + } = self.camera + { modelview_transform.pitch += pitch; modelview_transform.yaw += yaw; } @@ -352,21 +368,20 @@ impl DemoApp where W: Window { *scene_transform = eye_transforms[0]; for (index, eye_transform) in eye_transforms.iter().enumerate().skip(1) { let weight = 1.0 / (index + 1) as f32; - scene_transform.perspective.transform = - scene_transform.perspective - .transform - .lerp(weight, &eye_transform.perspective.transform); - scene_transform.modelview_to_eye = - scene_transform.modelview_to_eye - .lerp(weight, &eye_transform.modelview_to_eye); - } + scene_transform.perspective.transform = scene_transform + .perspective + .transform + .lerp(weight, &eye_transform.perspective.transform); + scene_transform.modelview_to_eye = scene_transform + .modelview_to_eye + .lerp(weight, &eye_transform.modelview_to_eye); + } // TODO: calculate the eye offset from the eye transforms? - let z_offset = -DEFAULT_EYE_OFFSET * - scene_transform.perspective.transform.c0.x(); + let z_offset = + -DEFAULT_EYE_OFFSET * scene_transform.perspective.transform.c0.x(); let z_offset = Vector4F::new(0.0, 0.0, z_offset, 1.0); - scene_transform.modelview_to_eye = - Transform4F::from_translation(z_offset) * - scene_transform.modelview_to_eye; + scene_transform.modelview_to_eye = Transform4F::from_translation(z_offset) + * scene_transform.modelview_to_eye; } } Event::KeyDown(Keycode::Alphanumeric(b'w')) => { @@ -452,9 +467,11 @@ impl DemoApp where W: Window { let viewport_size = self.window.viewport(self.ui_model.mode.view(0)).size(); self.scene_metadata = SceneMetadata::new_clipping_view_box(&mut scene, viewport_size); - self.camera = Camera::new(self.ui_model.mode, - self.scene_metadata.view_box, - viewport_size); + self.camera = Camera::new( + self.ui_model.mode, + self.scene_metadata.view_box, + viewport_size, + ); self.scene_proxy.replace_scene(scene); @@ -498,19 +515,28 @@ impl DemoApp where W: Window { .push(*ui_event); } - self.renderer.debug_ui_presenter_mut().debug_ui_presenter.ui_presenter.mouse_position = + self.renderer + .debug_ui_presenter_mut() + .debug_ui_presenter + .ui_presenter + .mouse_position = self.last_mouse_position.to_f32() * self.window_size.backing_scale_factor; let mut ui_action = UIAction::None; if self.options.ui == UIVisibility::All { - let DebugUIPresenterInfo { device, allocator, debug_ui_presenter } = - self.renderer.debug_ui_presenter_mut(); - self.ui_presenter.update(device, - allocator, - &mut self.window, - debug_ui_presenter, - &mut ui_action, - &mut self.ui_model); + let DebugUIPresenterInfo { + device, + allocator, + debug_ui_presenter, + } = self.renderer.debug_ui_presenter_mut(); + self.ui_presenter.update( + device, + allocator, + &mut self.window, + debug_ui_presenter, + &mut ui_action, + &mut self.ui_model, + ); } self.handle_ui_events(frame, &mut ui_action); @@ -524,24 +550,32 @@ impl DemoApp where W: Window { fn maybe_take_screenshot(&mut self) { match self.pending_screenshot_info.take() { None => {} - Some(ScreenshotInfo { kind: ScreenshotType::PNG, path }) => { - self.take_raster_screenshot(path) - } - Some(ScreenshotInfo { kind: ScreenshotType::SVG, path }) => { + Some(ScreenshotInfo { + kind: ScreenshotType::PNG, + path, + }) => self.take_raster_screenshot(path), + Some(ScreenshotInfo { + kind: ScreenshotType::SVG, + path, + }) => { // FIXME(pcwalton): This won't work on Android. let mut writer = BufWriter::new(File::create(path).unwrap()); - self.scene_proxy.copy_scene().export(&mut writer, FileFormat::SVG).unwrap(); + self.scene_proxy + .copy_scene() + .export(&mut writer, FileFormat::SVG) + .unwrap(); } } } fn handle_ui_events(&mut self, mut frame: Frame, ui_action: &mut UIAction) { - frame.ui_events = self.renderer - .debug_ui_presenter_mut() - .debug_ui_presenter - .ui_presenter - .event_queue - .drain(); + frame.ui_events = self + .renderer + .debug_ui_presenter_mut() + .debug_ui_presenter + .ui_presenter + .event_queue + .drain(); self.handle_ui_action(ui_action); @@ -550,9 +584,11 @@ impl DemoApp where W: Window { // FIXME(pcwalton): This should really be an MVC setup. if self.camera.mode() != self.ui_model.mode { let viewport_size = self.window.viewport(self.ui_model.mode.view(0)).size(); - self.camera = Camera::new(self.ui_model.mode, - self.scene_metadata.view_box, - viewport_size); + self.camera = Camera::new( + self.ui_model.mode, + self.scene_metadata.view_box, + viewport_size, + ); } for ui_event in frame.ui_events { @@ -614,9 +650,10 @@ impl DemoApp where W: Window { if let Camera::TwoD(ref mut transform) = self.camera { let old_rotation = transform.rotation(); let center = center_of_window(&self.window_size); - *transform = transform.translate(-center) - .rotate(*theta - old_rotation) - .translate(center); + *transform = transform + .translate(-center) + .rotate(*theta - old_rotation) + .translate(center); } } } @@ -695,7 +732,7 @@ impl Options { Arg::with_name("high-performance-gpu") .short("g") .long("high-performance-gpu") - .help("Use the high-performance (discrete) GPU, if available") + .help("Use the high-performance (discrete) GPU, if available"), ) .arg( Arg::with_name("level") @@ -703,7 +740,7 @@ impl Options { .short("l") .help("Set the renderer feature level as a Direct3D version equivalent") .takes_value(true) - .possible_values(&["9", "11"]) + .possible_values(&["9", "11"]), ) .arg( Arg::with_name("INPUT") @@ -764,36 +801,52 @@ pub enum UIVisibility { } impl Content { - fn render(&mut self, viewport_size: Vector2I, filter: Option) -> (Scene, String) { + fn render( + &mut self, + viewport_size: Vector2I, + filter: Option, + ) -> (Scene, String) { match *self { Content::Svg(ref tree) => { let built_svg = build_svg_tree(&tree, viewport_size, filter); let message = get_svg_building_message(&built_svg); (built_svg.scene, message) } - Content::Pdf { ref file, ref mut cache, page_nr } => { + Content::Pdf { + ref file, + ref mut cache, + page_nr, + } => { let page = file.get_page(page_nr).expect("no such page"); let mut backend = SceneBackend::new(cache); - pdf_render::render_page(&mut backend, &file.resolver(), &page, Transform2F::default()).unwrap(); + pdf_render::render_page( + &mut backend, + &file.resolver(), + &page, + Transform2F::default(), + ) + .unwrap(); (backend.finish(), String::new()) } } } } -fn load_scene(resource_loader: &dyn ResourceLoader, - input_path: &DataPath,) - -> Content { +fn load_scene(resource_loader: &dyn ResourceLoader, input_path: &DataPath) -> Content { let data = match *input_path { DataPath::Default => resource_loader.slurp(DEFAULT_SVG_VIRTUAL_PATH).unwrap(), DataPath::Resource(ref name) => resource_loader.slurp(name).unwrap(), - DataPath::Path(ref path) => std::fs::read(path).unwrap().into() + DataPath::Path(ref path) => std::fs::read(path).unwrap().into(), }; if let Ok(tree) = SvgTree::from_data(&data, &UsvgOptions::default()) { Content::Svg(tree) } else if let Ok(file) = FileOptions::cached().load(data) { - Content::Pdf { file, cache: PdfRenderCache::new(), page_nr: 0 } + Content::Pdf { + file, + cache: PdfRenderCache::new(), + page_nr: 0, + } } else { panic!("can't load data"); } @@ -801,22 +854,38 @@ fn load_scene(resource_loader: &dyn ResourceLoader, // FIXME(pcwalton): Rework how transforms work in the demo. The transform affects the final // composite steps, breaking this approach. -fn build_svg_tree(tree: &SvgTree, viewport_size: Vector2I, filter: Option) -> SVGScene { +fn build_svg_tree( + tree: &SvgTree, + viewport_size: Vector2I, + filter: Option, +) -> SVGScene { let mut scene = Scene::new(); let filter_info = filter.map(|filter| { let scale = match filter { - PatternFilter::Text { defringing_kernel: Some(_), .. } => vec2i(3, 1), + PatternFilter::Text { + defringing_kernel: Some(_), + .. + } => vec2i(3, 1), _ => vec2i(1, 1), }; let name = "Text".to_owned(); let render_target_size = viewport_size * scale; let render_target = RenderTarget::new(render_target_size, name); let render_target_id = scene.push_render_target(render_target); - FilterInfo { filter, render_target_id, render_target_size } + FilterInfo { + filter, + render_target_id, + render_target_size, + } }); let mut built_svg = SVGScene::from_tree_and_scene(&tree, scene); - if let Some(FilterInfo { filter, render_target_id, render_target_size }) = filter_info { + if let Some(FilterInfo { + filter, + render_target_id, + render_target_size, + }) = filter_info + { let mut pattern = Pattern::from_render_target(render_target_id, render_target_size); pattern.set_filter(Some(filter)); let paint_id = built_svg.scene.push_paint(&Paint::from_pattern(pattern)); @@ -879,7 +948,10 @@ struct Frame { impl Frame { fn new(transform: RenderTransform, ui_events: Vec) -> Frame { - Frame { transform, ui_events } + Frame { + transform, + ui_events, + } } } @@ -928,6 +1000,6 @@ fn build_filter(ui_model: &DemoUIModel) -> Option { Some(DEFRINGING_KERNEL_CORE_GRAPHICS) } else { None - } + }, }) } diff --git a/demo/common/src/renderer.rs b/demo/common/src/renderer.rs index 1dc770f8..1ef4ac0b 100644 --- a/demo/common/src/renderer.rs +++ b/demo/common/src/renderer.rs @@ -15,11 +15,11 @@ use crate::window::{View, Window}; use crate::{BackgroundColor, DemoApp, UIVisibility}; use image::ColorType; use pathfinder_color::{ColorF, ColorU}; -use pathfinder_gpu::{ClearOps, DepthFunc, DepthState, Device, Primitive, RenderOptions}; -use pathfinder_gpu::{RenderState, RenderTarget, TextureData, TextureFormat, UniformData}; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::transform3d::Transform4F; use pathfinder_geometry::vector::{Vector2I, Vector4F}; +use pathfinder_gpu::{ClearOps, DepthFunc, DepthState, Device, Primitive, RenderOptions}; +use pathfinder_gpu::{RenderState, RenderTarget, TextureData, TextureFormat, UniformData}; use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions}; use pathfinder_renderer::options::RenderTransform; use std::mem; @@ -41,7 +41,10 @@ const GROUND_LINE_COLOR: ColorU = ColorU { const GRIDLINE_COUNT: i32 = 10; -impl DemoApp where W: Window { +impl DemoApp +where + W: Window, +{ pub fn prepare_frame_rendering(&mut self) -> u32 { // Make the context current. let view = self.ui_model.mode.view(0); @@ -62,9 +65,10 @@ impl DemoApp where W: Window { let viewport = self.window.viewport(View::Stereo(0)); if self.scene_framebuffer.is_none() || self.renderer.device().texture_size( - &self.renderer.device().framebuffer_texture(self.scene_framebuffer - .as_ref() - .unwrap()), + &self + .renderer + .device() + .framebuffer_texture(self.scene_framebuffer.as_ref().unwrap()), ) != viewport.size() { let scene_texture = self @@ -120,9 +124,9 @@ impl DemoApp where W: Window { }, ..*self.renderer.options() }; - if let DestFramebuffer::Other(scene_framebuffer) = mem::replace(self.renderer - .options_mut(), - new_options).dest { + if let DestFramebuffer::Other(scene_framebuffer) = + mem::replace(self.renderer.options_mut(), new_options).dest + { self.scene_framebuffer = Some(scene_framebuffer); } } @@ -165,22 +169,25 @@ impl DemoApp where W: Window { self.draw_environment(render_scene_index); let scene_framebuffer = self.scene_framebuffer.as_ref().unwrap(); - let scene_texture = self.renderer.device().framebuffer_texture(scene_framebuffer); + let scene_texture = self + .renderer + .device() + .framebuffer_texture(scene_framebuffer); let mut quad_scale = self.scene_metadata.view_box.size().to_4d(); quad_scale.set_z(1.0); let quad_scale_transform = Transform4F::from_scale(quad_scale); - let scene_transform_matrix = scene_transform.perspective * - scene_transform.modelview_to_eye * - modelview_transform.to_transform() * - quad_scale_transform; + let scene_transform_matrix = scene_transform.perspective + * scene_transform.modelview_to_eye + * modelview_transform.to_transform() + * quad_scale_transform; let eye_transform = &eye_transforms[render_scene_index as usize]; - let eye_transform_matrix = eye_transform.perspective * - eye_transform.modelview_to_eye * - modelview_transform.to_transform() * - quad_scale_transform; + let eye_transform_matrix = eye_transform.perspective + * eye_transform.modelview_to_eye + * modelview_transform.to_transform() + * quad_scale_transform; debug!( "eye transform({}).modelview_to_eye={:?}", @@ -220,8 +227,8 @@ impl DemoApp where W: Window { let base_transform = perspective.transform * Transform4F::from_translation(offset); // Fill ground. - let transform = base_transform * - Transform4F::from_scale(Vector4F::new(ground_scale, 1.0, ground_scale, 1.0)); + let transform = base_transform + * Transform4F::from_scale(Vector4F::new(ground_scale, 1.0, ground_scale, 1.0)); // Don't clear the first scene after drawing it. let clear_color = if render_scene_index == 0 { @@ -230,30 +237,49 @@ impl DemoApp where W: Window { None }; - self.renderer.device().draw_elements(6, &RenderState { - target: &self.renderer.draw_render_target(), - program: &self.ground_program.program, - vertex_array: &self.ground_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[], - images: &[], - storage_buffers: &[], - uniforms: &[ - (&self.ground_program.transform_uniform, - UniformData::from_transform_3d(&transform)), - (&self.ground_program.ground_color_uniform, - UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0)), - (&self.ground_program.gridline_color_uniform, - UniformData::Vec4(GROUND_LINE_COLOR.to_f32().0)), - (&self.ground_program.gridline_count_uniform, UniformData::Int(GRIDLINE_COUNT)), - ], - viewport: self.renderer.draw_viewport(), - options: RenderOptions { - depth: Some(DepthState { func: DepthFunc::Less, write: true }), - clear_ops: ClearOps { color: clear_color, depth: Some(1.0), stencil: Some(0) }, - ..RenderOptions::default() + self.renderer.device().draw_elements( + 6, + &RenderState { + target: &self.renderer.draw_render_target(), + program: &self.ground_program.program, + vertex_array: &self.ground_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[], + images: &[], + storage_buffers: &[], + uniforms: &[ + ( + &self.ground_program.transform_uniform, + UniformData::from_transform_3d(&transform), + ), + ( + &self.ground_program.ground_color_uniform, + UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0), + ), + ( + &self.ground_program.gridline_color_uniform, + UniformData::Vec4(GROUND_LINE_COLOR.to_f32().0), + ), + ( + &self.ground_program.gridline_count_uniform, + UniformData::Int(GRIDLINE_COUNT), + ), + ], + viewport: self.renderer.draw_viewport(), + options: RenderOptions { + depth: Some(DepthState { + func: DepthFunc::Less, + write: true, + }), + clear_ops: ClearOps { + color: clear_color, + depth: Some(1.0), + stencil: Some(0), + }, + ..RenderOptions::default() + }, }, - }); + ); } #[allow(deprecated)] @@ -271,9 +297,15 @@ impl DemoApp where W: Window { pub fn take_raster_screenshot(&mut self, path: PathBuf) { let drawable_size = self.window_size.device_size(); let viewport = RectI::new(Vector2I::default(), drawable_size); - let texture_data_receiver = - self.renderer.device().read_pixels(&RenderTarget::Default, viewport); - let pixels = match self.renderer.device().recv_texture_data(&texture_data_receiver) { + let texture_data_receiver = self + .renderer + .device() + .read_pixels(&RenderTarget::Default, viewport); + let pixels = match self + .renderer + .device() + .recv_texture_data(&texture_data_receiver) + { TextureData::U8(pixels) => pixels, _ => panic!("Unexpected pixel format for default framebuffer!"), }; diff --git a/demo/common/src/ui.rs b/demo/common/src/ui.rs index e1825478..e6f07e70 100644 --- a/demo/common/src/ui.rs +++ b/demo/common/src/ui.rs @@ -13,7 +13,7 @@ use crate::window::Window; use crate::{BackgroundColor, Options}; use pathfinder_color::ColorU; use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::{Vector2I, vec2i}; +use pathfinder_geometry::vector::{vec2i, Vector2I}; use pathfinder_gpu::allocator::GPUMemoryAllocator; use pathfinder_gpu::{Device, TextureFormat}; use pathfinder_renderer::gpu::debug::DebugUIPresenter; @@ -41,9 +41,24 @@ const SCREENSHOT_PANEL_HEIGHT: i32 = BUTTON_HEIGHT * 2; const ROTATE_PANEL_WIDTH: i32 = SLIDER_WIDTH + PADDING * 2; const ROTATE_PANEL_HEIGHT: i32 = PADDING * 2 + SLIDER_HEIGHT; -const LIGHT_BG_COLOR: ColorU = ColorU { r: 248, g: 248, b: 248, a: 255, }; -const DARK_BG_COLOR: ColorU = ColorU { r: 32, g: 32, b: 32, a: 255, }; -const TRANSPARENT_BG_COLOR: ColorU = ColorU { r: 0, g: 0, b: 0, a: 0, }; +const LIGHT_BG_COLOR: ColorU = ColorU { + r: 248, + g: 248, + b: 248, + a: 255, +}; +const DARK_BG_COLOR: ColorU = ColorU { + r: 32, + g: 32, + b: 32, + a: 255, +}; +const TRANSPARENT_BG_COLOR: ColorU = ColorU { + r: 0, + g: 0, + b: 0, + a: 0, +}; static EFFECTS_PNG_NAME: &'static str = "demo-effects"; static OPEN_PNG_NAME: &'static str = "demo-open"; @@ -98,7 +113,10 @@ impl DemoUIModel { } } -pub struct DemoUIPresenter where D: Device { +pub struct DemoUIPresenter +where + D: Device, +{ effects_texture: D::Texture, open_texture: D::Texture, rotate_texture: D::Texture, @@ -114,34 +132,29 @@ pub struct DemoUIPresenter where D: Device { rotate_panel_visible: bool, } -impl DemoUIPresenter where D: Device { +impl DemoUIPresenter +where + D: Device, +{ pub fn new(device: &D, resources: &dyn ResourceLoader) -> DemoUIPresenter { device.begin_commands(); - let effects_texture = device.create_texture_from_png(resources, - EFFECTS_PNG_NAME, - TextureFormat::R8); - let open_texture = device.create_texture_from_png(resources, - OPEN_PNG_NAME, - TextureFormat::R8); - let rotate_texture = device.create_texture_from_png(resources, - ROTATE_PNG_NAME, - TextureFormat::R8); - let zoom_in_texture = device.create_texture_from_png(resources, - ZOOM_IN_PNG_NAME, - TextureFormat::R8); - let zoom_actual_size_texture = device.create_texture_from_png(resources, - ZOOM_ACTUAL_SIZE_PNG_NAME, - TextureFormat::R8); - let zoom_out_texture = device.create_texture_from_png(resources, - ZOOM_OUT_PNG_NAME, - TextureFormat::R8); - let background_texture = device.create_texture_from_png(resources, - BACKGROUND_PNG_NAME, - TextureFormat::R8); - let screenshot_texture = device.create_texture_from_png(resources, - SCREENSHOT_PNG_NAME, - TextureFormat::R8); + let effects_texture = + device.create_texture_from_png(resources, EFFECTS_PNG_NAME, TextureFormat::R8); + let open_texture = + device.create_texture_from_png(resources, OPEN_PNG_NAME, TextureFormat::R8); + let rotate_texture = + device.create_texture_from_png(resources, ROTATE_PNG_NAME, TextureFormat::R8); + let zoom_in_texture = + device.create_texture_from_png(resources, ZOOM_IN_PNG_NAME, TextureFormat::R8); + let zoom_actual_size_texture = + device.create_texture_from_png(resources, ZOOM_ACTUAL_SIZE_PNG_NAME, TextureFormat::R8); + let zoom_out_texture = + device.create_texture_from_png(resources, ZOOM_OUT_PNG_NAME, TextureFormat::R8); + let background_texture = + device.create_texture_from_png(resources, BACKGROUND_PNG_NAME, TextureFormat::R8); + let screenshot_texture = + device.create_texture_from_png(resources, SCREENSHOT_PNG_NAME, TextureFormat::R8); device.end_commands(); @@ -162,14 +175,17 @@ impl DemoUIPresenter where D: Device { } } - pub fn update(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - window: &mut W, - debug_ui_presenter: &mut DebugUIPresenter, - action: &mut UIAction, - model: &mut DemoUIModel) - where W: Window { + pub fn update( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + window: &mut W, + debug_ui_presenter: &mut DebugUIPresenter, + action: &mut UIAction, + model: &mut DemoUIModel, + ) where + W: Window, + { // Draw message text. self.draw_message_text(device, allocator, debug_ui_presenter, model); @@ -182,34 +198,50 @@ impl DemoUIPresenter where D: Device { let button_size = vec2i(BUTTON_WIDTH, BUTTON_HEIGHT); // Draw effects button. - if debug_ui_presenter.ui_presenter - .draw_button(device, allocator, position, &self.effects_texture) { + if debug_ui_presenter.ui_presenter.draw_button( + device, + allocator, + position, + &self.effects_texture, + ) { self.effects_panel_visible = !self.effects_panel_visible; } if !self.effects_panel_visible { - debug_ui_presenter.ui_presenter.draw_tooltip(device, - allocator, - "Effects", - RectI::new(position, button_size)); + debug_ui_presenter.ui_presenter.draw_tooltip( + device, + allocator, + "Effects", + RectI::new(position, button_size), + ); } position += vec2i(button_size.x() + PADDING, 0); // Draw open button. - if debug_ui_presenter.ui_presenter - .draw_button(device, allocator, position, &self.open_texture) { + if debug_ui_presenter.ui_presenter.draw_button( + device, + allocator, + position, + &self.open_texture, + ) { // FIXME(pcwalton): This is not sufficient for Android, where we will need to take in // the contents of the file. window.present_open_svg_dialog(); } - debug_ui_presenter.ui_presenter.draw_tooltip(device, - allocator, - "Open SVG", - RectI::new(position, button_size)); + debug_ui_presenter.ui_presenter.draw_tooltip( + device, + allocator, + "Open SVG", + RectI::new(position, button_size), + ); position += vec2i(BUTTON_WIDTH + PADDING, 0); // Draw screenshot button. - if debug_ui_presenter.ui_presenter - .draw_button(device, allocator, position, &self.screenshot_texture) { + if debug_ui_presenter.ui_presenter.draw_button( + device, + allocator, + position, + &self.screenshot_texture, + ) { self.screenshot_panel_visible = !self.screenshot_panel_visible; } if !self.screenshot_panel_visible { @@ -222,20 +254,24 @@ impl DemoUIPresenter where D: Device { } // Draw screenshot panel, if necessary. - self.draw_screenshot_panel(device, - allocator, - window, - debug_ui_presenter, - position.x(), - action); + self.draw_screenshot_panel( + device, + allocator, + window, + debug_ui_presenter, + position.x(), + action, + ); position += vec2i(button_size.x() + PADDING, 0); // Draw mode switch. - let new_mode = debug_ui_presenter.ui_presenter.draw_text_switch(device, - allocator, - position, - &["2D", "3D", "VR"], - model.mode as u8); + let new_mode = debug_ui_presenter.ui_presenter.draw_text_switch( + device, + allocator, + position, + &["2D", "3D", "VR"], + model.mode as u8, + ); if new_mode != model.mode as u8 { model.mode = match new_mode { 0 => Mode::TwoD, @@ -256,10 +292,12 @@ impl DemoUIPresenter where D: Device { position += vec2i(mode_switch_width + PADDING, 0); // Draw background switch. - if debug_ui_presenter.ui_presenter.draw_button(device, - allocator, - position, - &self.background_texture) { + if debug_ui_presenter.ui_presenter.draw_button( + device, + allocator, + position, + &self.background_texture, + ) { self.background_panel_visible = !self.background_panel_visible; } if !self.background_panel_visible { @@ -272,12 +310,14 @@ impl DemoUIPresenter where D: Device { } // Draw background panel, if necessary. - self.draw_background_panel(device, - allocator, - debug_ui_presenter, - position.x(), - action, - model); + self.draw_background_panel( + device, + allocator, + debug_ui_presenter, + position.x(), + action, + model, + ); position += vec2i(button_size.x() + PADDING, 0); // Draw effects panel, if necessary. @@ -288,49 +328,65 @@ impl DemoUIPresenter where D: Device { return; } - if debug_ui_presenter.ui_presenter.draw_button(device, - allocator, - position, - &self.rotate_texture) { + if debug_ui_presenter.ui_presenter.draw_button( + device, + allocator, + position, + &self.rotate_texture, + ) { self.rotate_panel_visible = !self.rotate_panel_visible; } if !self.rotate_panel_visible { - debug_ui_presenter.ui_presenter.draw_tooltip(device, - allocator, - "Rotate", - RectI::new(position, button_size)); + debug_ui_presenter.ui_presenter.draw_tooltip( + device, + allocator, + "Rotate", + RectI::new(position, button_size), + ); } - self.draw_rotate_panel(device, allocator, debug_ui_presenter, position.x(), action, model); + self.draw_rotate_panel( + device, + allocator, + debug_ui_presenter, + position.x(), + action, + model, + ); position += vec2i(BUTTON_WIDTH + PADDING, 0); // Draw zoom control. self.draw_zoom_control(device, allocator, debug_ui_presenter, position, action); } - fn draw_zoom_control(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - debug_ui_presenter: &mut DebugUIPresenter, - position: Vector2I, - action: &mut UIAction) { + fn draw_zoom_control( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + debug_ui_presenter: &mut DebugUIPresenter, + position: Vector2I, + action: &mut UIAction, + ) { let zoom_segmented_control_width = debug_ui_presenter.ui_presenter.measure_segmented_control(3); let zoom_segmented_control_rect = RectI::new(position, vec2i(zoom_segmented_control_width, BUTTON_HEIGHT)); - debug_ui_presenter.ui_presenter - .draw_tooltip(device, allocator, "Zoom", zoom_segmented_control_rect); + debug_ui_presenter.ui_presenter.draw_tooltip( + device, + allocator, + "Zoom", + zoom_segmented_control_rect, + ); let zoom_textures = &[ &self.zoom_in_texture, &self.zoom_actual_size_texture, - &self.zoom_out_texture + &self.zoom_out_texture, ]; - match debug_ui_presenter.ui_presenter.draw_image_segmented_control(device, - allocator, - position, - zoom_textures, - None) { + match debug_ui_presenter + .ui_presenter + .draw_image_segmented_control(device, allocator, position, zoom_textures, None) + { Some(0) => *action = UIAction::ZoomIn, Some(1) => *action = UIAction::ZoomActualSize, Some(2) => *action = UIAction::ZoomOut, @@ -338,11 +394,13 @@ impl DemoUIPresenter where D: Device { } } - fn draw_message_text(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - debug_ui_presenter: &mut DebugUIPresenter, - model: &mut DemoUIModel) { + fn draw_message_text( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + debug_ui_presenter: &mut DebugUIPresenter, + model: &mut DemoUIModel, + ) { if model.message.is_empty() { return; } @@ -365,12 +423,14 @@ impl DemoUIPresenter where D: Device { ); } - fn draw_effects_panel(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - debug_ui_presenter: &mut DebugUIPresenter, - model: &mut DemoUIModel, - action: &mut UIAction) { + fn draw_effects_panel( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + debug_ui_presenter: &mut DebugUIPresenter, + model: &mut DemoUIModel, + action: &mut UIAction, + ) { if !self.effects_panel_visible { return; } @@ -380,44 +440,56 @@ impl DemoUIPresenter where D: Device { debug_ui_presenter.ui_presenter.draw_solid_rounded_rect( device, allocator, - RectI::new(vec2i(PADDING, effects_panel_y), - vec2i(EFFECTS_PANEL_WIDTH, EFFECTS_PANEL_HEIGHT)), - WINDOW_COLOR); + RectI::new( + vec2i(PADDING, effects_panel_y), + vec2i(EFFECTS_PANEL_WIDTH, EFFECTS_PANEL_HEIGHT), + ), + WINDOW_COLOR, + ); - self.draw_effects_switch(device, - allocator, - action, - debug_ui_presenter, - "Gamma Correction", - 0, - effects_panel_y, - &mut model.gamma_correction_effect_enabled); - self.draw_effects_switch(device, - allocator, - action, - debug_ui_presenter, - "Stem Darkening", - 1, - effects_panel_y, - &mut model.stem_darkening_effect_enabled); - self.draw_effects_switch(device, - allocator, - action, - debug_ui_presenter, - "Subpixel AA", - 2, - effects_panel_y, - &mut model.subpixel_aa_effect_enabled); + self.draw_effects_switch( + device, + allocator, + action, + debug_ui_presenter, + "Gamma Correction", + 0, + effects_panel_y, + &mut model.gamma_correction_effect_enabled, + ); + self.draw_effects_switch( + device, + allocator, + action, + debug_ui_presenter, + "Stem Darkening", + 1, + effects_panel_y, + &mut model.stem_darkening_effect_enabled, + ); + self.draw_effects_switch( + device, + allocator, + action, + debug_ui_presenter, + "Subpixel AA", + 2, + effects_panel_y, + &mut model.subpixel_aa_effect_enabled, + ); } - fn draw_screenshot_panel(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - window: &mut W, - debug_ui_presenter: &mut DebugUIPresenter, - panel_x: i32, - action: &mut UIAction) - where W: Window { + fn draw_screenshot_panel( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + window: &mut W, + debug_ui_presenter: &mut DebugUIPresenter, + panel_x: i32, + action: &mut UIAction, + ) where + W: Window, + { if !self.screenshot_panel_visible { return; } @@ -428,33 +500,42 @@ impl DemoUIPresenter where D: Device { debug_ui_presenter.ui_presenter.draw_solid_rounded_rect( device, allocator, - RectI::new(panel_position, vec2i(SCREENSHOT_PANEL_WIDTH, SCREENSHOT_PANEL_HEIGHT)), + RectI::new( + panel_position, + vec2i(SCREENSHOT_PANEL_WIDTH, SCREENSHOT_PANEL_HEIGHT), + ), WINDOW_COLOR, ); - self.draw_screenshot_menu_item(device, - allocator, - window, - debug_ui_presenter, - ScreenshotType::PNG, - panel_position, - action); - self.draw_screenshot_menu_item(device, - allocator, - window, - debug_ui_presenter, - ScreenshotType::SVG, - panel_position, - action); + self.draw_screenshot_menu_item( + device, + allocator, + window, + debug_ui_presenter, + ScreenshotType::PNG, + panel_position, + action, + ); + self.draw_screenshot_menu_item( + device, + allocator, + window, + debug_ui_presenter, + ScreenshotType::SVG, + panel_position, + action, + ); } - fn draw_background_panel(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - debug_ui_presenter: &mut DebugUIPresenter, - panel_x: i32, - action: &mut UIAction, - model: &mut DemoUIModel) { + fn draw_background_panel( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + debug_ui_presenter: &mut DebugUIPresenter, + panel_x: i32, + action: &mut UIAction, + model: &mut DemoUIModel, + ) { if !self.background_panel_visible { return; } @@ -465,40 +546,51 @@ impl DemoUIPresenter where D: Device { debug_ui_presenter.ui_presenter.draw_solid_rounded_rect( device, allocator, - RectI::new(panel_position, vec2i(BACKGROUND_PANEL_WIDTH, BACKGROUND_PANEL_HEIGHT)), + RectI::new( + panel_position, + vec2i(BACKGROUND_PANEL_WIDTH, BACKGROUND_PANEL_HEIGHT), + ), WINDOW_COLOR, ); - self.draw_background_menu_item(device, - allocator, - debug_ui_presenter, - BackgroundColor::Light, - panel_position, - action, - model); - self.draw_background_menu_item(device, - allocator, - debug_ui_presenter, - BackgroundColor::Dark, - panel_position, - action, - model); - self.draw_background_menu_item(device, - allocator, - debug_ui_presenter, - BackgroundColor::Transparent, - panel_position, - action, - model); + self.draw_background_menu_item( + device, + allocator, + debug_ui_presenter, + BackgroundColor::Light, + panel_position, + action, + model, + ); + self.draw_background_menu_item( + device, + allocator, + debug_ui_presenter, + BackgroundColor::Dark, + panel_position, + action, + model, + ); + self.draw_background_menu_item( + device, + allocator, + debug_ui_presenter, + BackgroundColor::Transparent, + panel_position, + action, + model, + ); } - fn draw_rotate_panel(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - debug_ui_presenter: &mut DebugUIPresenter, - rotate_panel_x: i32, - action: &mut UIAction, - model: &mut DemoUIModel) { + fn draw_rotate_panel( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + debug_ui_presenter: &mut DebugUIPresenter, + rotate_panel_x: i32, + action: &mut UIAction, + model: &mut DemoUIModel, + ) { if !self.rotate_panel_visible { return; } @@ -511,42 +603,61 @@ impl DemoUIPresenter where D: Device { device, allocator, RectI::new(rotate_panel_origin, rotate_panel_size), - WINDOW_COLOR); + WINDOW_COLOR, + ); let (widget_x, widget_y) = (rotate_panel_x + PADDING, rotate_panel_y + PADDING); - let widget_rect = RectI::new(vec2i(widget_x, widget_y), - vec2i(SLIDER_WIDTH, SLIDER_KNOB_HEIGHT)); + let widget_rect = RectI::new( + vec2i(widget_x, widget_y), + vec2i(SLIDER_WIDTH, SLIDER_KNOB_HEIGHT), + ); if let Some(position) = debug_ui_presenter .ui_presenter .event_queue - .handle_mouse_down_or_dragged_in_rect(widget_rect) { + .handle_mouse_down_or_dragged_in_rect(widget_rect) + { model.rotation = position.x(); *action = UIAction::Rotate(model.rotation()); } let slider_track_y = rotate_panel_y + PADDING + SLIDER_KNOB_HEIGHT / 2 - SLIDER_TRACK_HEIGHT / 2; - let slider_track_rect = RectI::new(vec2i(widget_x, slider_track_y), - vec2i(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT)); - debug_ui_presenter.ui_presenter - .draw_rect_outline(device, allocator, slider_track_rect, TEXT_COLOR); + let slider_track_rect = RectI::new( + vec2i(widget_x, slider_track_y), + vec2i(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT), + ); + debug_ui_presenter.ui_presenter.draw_rect_outline( + device, + allocator, + slider_track_rect, + TEXT_COLOR, + ); let slider_knob_x = widget_x + model.rotation - SLIDER_KNOB_WIDTH / 2; - let slider_knob_rect = RectI::new(vec2i(slider_knob_x, widget_y), - vec2i(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT)); - debug_ui_presenter.ui_presenter - .draw_solid_rect(device, allocator, slider_knob_rect, TEXT_COLOR); + let slider_knob_rect = RectI::new( + vec2i(slider_knob_x, widget_y), + vec2i(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT), + ); + debug_ui_presenter.ui_presenter.draw_solid_rect( + device, + allocator, + slider_knob_rect, + TEXT_COLOR, + ); } - fn draw_screenshot_menu_item(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - window: &mut W, - debug_ui_presenter: &mut DebugUIPresenter, - screenshot_type: ScreenshotType, - panel_position: Vector2I, - action: &mut UIAction) - where W: Window { + fn draw_screenshot_menu_item( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + window: &mut W, + debug_ui_presenter: &mut DebugUIPresenter, + screenshot_type: ScreenshotType, + panel_position: Vector2I, + action: &mut UIAction, + ) where + W: Window, + { let index = screenshot_type as i32; let text = format!("Save as {}...", screenshot_type.as_str()); @@ -554,29 +665,36 @@ impl DemoUIPresenter where D: Device { let widget_origin = panel_position + vec2i(0, widget_size.y() * index); let widget_rect = RectI::new(widget_origin, widget_size); - if self.draw_menu_item(device, - allocator, - debug_ui_presenter, - &text, - widget_rect, - false) { + if self.draw_menu_item( + device, + allocator, + debug_ui_presenter, + &text, + widget_rect, + false, + ) { // FIXME(pcwalton): This is not sufficient for Android, where we will need to take in // the contents of the file. if let Ok(path) = window.run_save_dialog(screenshot_type.extension()) { self.screenshot_panel_visible = false; - *action = UIAction::TakeScreenshot(ScreenshotInfo { kind: screenshot_type, path }); + *action = UIAction::TakeScreenshot(ScreenshotInfo { + kind: screenshot_type, + path, + }); } } } - fn draw_background_menu_item(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - debug_ui_presenter: &mut DebugUIPresenter, - color: BackgroundColor, - panel_position: Vector2I, - action: &mut UIAction, - model: &mut DemoUIModel) { + fn draw_background_menu_item( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + debug_ui_presenter: &mut DebugUIPresenter, + color: BackgroundColor, + panel_position: Vector2I, + action: &mut UIAction, + model: &mut DemoUIModel, + ) { let (text, index) = (color.as_str(), color as i32); let widget_size = vec2i(BACKGROUND_PANEL_WIDTH, BUTTON_HEIGHT); @@ -584,66 +702,83 @@ impl DemoUIPresenter where D: Device { let widget_rect = RectI::new(widget_origin, widget_size); let selected = color == model.background_color; - if self.draw_menu_item(device, - allocator, - debug_ui_presenter, - text, - widget_rect, - selected) { + if self.draw_menu_item( + device, + allocator, + debug_ui_presenter, + text, + widget_rect, + selected, + ) { model.background_color = color; *action = UIAction::ModelChanged; } } - fn draw_menu_item(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - debug_ui_presenter: &mut DebugUIPresenter, - text: &str, - widget_rect: RectI, - selected: bool) - -> bool { + fn draw_menu_item( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + debug_ui_presenter: &mut DebugUIPresenter, + text: &str, + widget_rect: RectI, + selected: bool, + ) -> bool { if selected { - debug_ui_presenter.ui_presenter - .draw_solid_rounded_rect(device, allocator, widget_rect, TEXT_COLOR); + debug_ui_presenter.ui_presenter.draw_solid_rounded_rect( + device, + allocator, + widget_rect, + TEXT_COLOR, + ); } let (text_x, text_y) = (PADDING * 2, BUTTON_TEXT_OFFSET); let text_position = widget_rect.origin() + vec2i(text_x, text_y); - debug_ui_presenter.ui_presenter - .draw_text(device, allocator, text, text_position, selected); + debug_ui_presenter + .ui_presenter + .draw_text(device, allocator, text, text_position, selected); - debug_ui_presenter.ui_presenter - .event_queue - .handle_mouse_down_in_rect(widget_rect) - .is_some() + debug_ui_presenter + .ui_presenter + .event_queue + .handle_mouse_down_in_rect(widget_rect) + .is_some() } - fn draw_effects_switch(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - action: &mut UIAction, - debug_ui_presenter: &mut DebugUIPresenter, - text: &str, - index: i32, - window_y: i32, - value: &mut bool) { + fn draw_effects_switch( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + action: &mut UIAction, + debug_ui_presenter: &mut DebugUIPresenter, + text: &str, + index: i32, + window_y: i32, + value: &mut bool, + ) { let text_x = PADDING * 2; let text_y = window_y + PADDING + BUTTON_TEXT_OFFSET + (BUTTON_HEIGHT + PADDING) * index; - debug_ui_presenter.ui_presenter - .draw_text(device, allocator, text, vec2i(text_x, text_y), false); + debug_ui_presenter.ui_presenter.draw_text( + device, + allocator, + text, + vec2i(text_x, text_y), + false, + ); let switch_width = debug_ui_presenter.ui_presenter.measure_segmented_control(2); let switch_x = PADDING + EFFECTS_PANEL_WIDTH - (switch_width + PADDING); let switch_y = window_y + PADDING + (BUTTON_HEIGHT + PADDING) * index; let switch_position = vec2i(switch_x, switch_y); - let new_value = debug_ui_presenter.ui_presenter - .draw_text_switch(device, - allocator, - switch_position, - &["Off", "On"], - *value as u8) != 0; + let new_value = debug_ui_presenter.ui_presenter.draw_text_switch( + device, + allocator, + switch_position, + &["Off", "On"], + *value as u8, + ) != 0; if new_value != *value { *action = UIAction::EffectsChanged; diff --git a/demo/common/src/window.rs b/demo/common/src/window.rs index eec4b8a0..677fb2a3 100644 --- a/demo/common/src/window.rs +++ b/demo/common/src/window.rs @@ -33,7 +33,9 @@ pub trait Window { #[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] fn gl_version(&self) -> GLVersion; #[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] - fn gl_default_framebuffer(&self) -> GLuint { 0 } + fn gl_default_framebuffer(&self) -> GLuint { + 0 + } #[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] fn present(&mut self, device: &mut GLDevice); diff --git a/demo/magicleap/Cargo.toml b/demo/magicleap/Cargo.toml index 79345419..23cb0a8b 100644 --- a/demo/magicleap/Cargo.toml +++ b/demo/magicleap/Cargo.toml @@ -7,7 +7,7 @@ authors = ["Alan Jeffrey "] [dependencies] gl = "0.14" rayon = "1.0" -usvg = "0.9" +usvg = "0.10" egl = "0.2" log = "0.4" smallvec = "1.2" diff --git a/demo/magicleap/src/c_api.rs b/demo/magicleap/src/c_api.rs index ee22f6f0..1baf7574 100644 --- a/demo/magicleap/src/c_api.rs +++ b/demo/magicleap/src/c_api.rs @@ -263,27 +263,51 @@ impl MLResult { } } -impl Error for MLResult { -} +impl Error for MLResult {} // Functions from the MagicLeap C API #[cfg(not(feature = "mocked"))] extern "C" { - pub fn MLGraphicsCreateClientGL(options: *const MLGraphicsOptions, gl_context: MLHandle, graphics_client : &mut MLHandle) -> MLResult; + pub fn MLGraphicsCreateClientGL( + options: *const MLGraphicsOptions, + gl_context: MLHandle, + graphics_client: &mut MLHandle, + ) -> MLResult; pub fn MLGraphicsDestroyClient(graphics_client: *mut MLHandle) -> MLResult; pub fn MLHeadTrackingCreate(tracker: *mut MLHandle) -> MLResult; - pub fn MLHeadTrackingGetStaticData(head_tracker: MLHandle, data: *mut MLHeadTrackingStaticData) -> MLResult; + pub fn MLHeadTrackingGetStaticData( + head_tracker: MLHandle, + data: *mut MLHeadTrackingStaticData, + ) -> MLResult; pub fn MLPerceptionGetSnapshot(snapshot: *mut MLSnapshotPtr) -> MLResult; - pub fn MLSnapshotGetTransform(snapshot: MLSnapshotPtr, id: *const MLCoordinateFrameUID, transform: *mut MLTransform) -> MLResult; + pub fn MLSnapshotGetTransform( + snapshot: MLSnapshotPtr, + id: *const MLCoordinateFrameUID, + transform: *mut MLTransform, + ) -> MLResult; pub fn MLPerceptionReleaseSnapshot(snapshot: MLSnapshotPtr) -> MLResult; pub fn MLLifecycleSetReadyIndication() -> MLResult; - pub fn MLGraphicsGetClipExtents(graphics_client: MLHandle, array: *mut MLGraphicsClipExtentsInfoArray) -> MLResult; - pub fn MLGraphicsGetRenderTargets(graphics_client: MLHandle, targets: *mut MLGraphicsRenderTargetsInfo) -> MLResult; + pub fn MLGraphicsGetClipExtents( + graphics_client: MLHandle, + array: *mut MLGraphicsClipExtentsInfoArray, + ) -> MLResult; + pub fn MLGraphicsGetRenderTargets( + graphics_client: MLHandle, + targets: *mut MLGraphicsRenderTargetsInfo, + ) -> MLResult; pub fn MLGraphicsInitFrameParams(params: *mut MLGraphicsFrameParams) -> MLResult; - pub fn MLGraphicsBeginFrame(graphics_client: MLHandle, params: *const MLGraphicsFrameParams, frame_handle: *mut MLHandle, virtual_camera_array: *mut MLGraphicsVirtualCameraInfoArray) -> MLResult; + pub fn MLGraphicsBeginFrame( + graphics_client: MLHandle, + params: *const MLGraphicsFrameParams, + frame_handle: *mut MLHandle, + virtual_camera_array: *mut MLGraphicsVirtualCameraInfoArray, + ) -> MLResult; pub fn MLGraphicsEndFrame(graphics_client: MLHandle, frame_handle: MLHandle) -> MLResult; - pub fn MLGraphicsSignalSyncObjectGL(graphics_client: MLHandle, sync_object: MLHandle) -> MLResult; + pub fn MLGraphicsSignalSyncObjectGL( + graphics_client: MLHandle, + sync_object: MLHandle, + ) -> MLResult; pub fn MLGetResultString(result_code: MLResult) -> *const c_char; pub fn MLLoggingLogLevelIsEnabled(lvl: MLLogLevel) -> bool; pub fn MLLoggingLog(lvl: MLLogLevel, tag: *const c_char, message: *const c_char); diff --git a/demo/magicleap/src/lib.rs b/demo/magicleap/src/lib.rs index 319c6826..6123e733 100644 --- a/demo/magicleap/src/lib.rs +++ b/demo/magicleap/src/lib.rs @@ -22,31 +22,31 @@ use gl::types::GLuint; use log::info; -use pathfinder_demo::DemoApp; -use pathfinder_demo::Options; -use pathfinder_demo::UIVisibility; -use pathfinder_demo::BackgroundColor; -use pathfinder_demo::Mode; +use pathfinder_color::ColorF; use pathfinder_demo::window::Event; use pathfinder_demo::window::SVGPath; +use pathfinder_demo::BackgroundColor; +use pathfinder_demo::DemoApp; +use pathfinder_demo::Mode; +use pathfinder_demo::Options; +use pathfinder_demo::UIVisibility; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::transform2d::Transform2F; +use pathfinder_geometry::vector::vec2i; use pathfinder_geometry::vector::Vector2F; use pathfinder_geometry::vector::Vector2I; -use pathfinder_geometry::vector::vec2i; -use pathfinder_color::ColorF; use pathfinder_gl::GLDevice; use pathfinder_gl::GLVersion; use pathfinder_gpu::ClearParams; use pathfinder_gpu::Device; use pathfinder_renderer::concurrent::executor::SequentialExecutor; use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; -use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::gpu::renderer::DestFramebuffer; +use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::options::RenderOptions; use pathfinder_renderer::options::RenderTransform; -use pathfinder_resources::ResourceLoader; use pathfinder_resources::fs::FilesystemResourceLoader; +use pathfinder_resources::ResourceLoader; use pathfinder_simd::default::F32x4; use pathfinder_svg::SVGScene; @@ -72,10 +72,17 @@ struct ImmersiveApp { } #[no_mangle] -pub extern "C" fn magicleap_pathfinder_demo_init(egl_display: EGLDisplay, egl_context: EGLContext) -> *mut c_void { - unsafe { c_api::MLLoggingLog(c_api::MLLogLevel::Info, - b"Pathfinder Demo\0".as_ptr() as *const _, - b"Initializing\0".as_ptr() as *const _) }; +pub extern "C" fn magicleap_pathfinder_demo_init( + egl_display: EGLDisplay, + egl_context: EGLContext, +) -> *mut c_void { + unsafe { + c_api::MLLoggingLog( + c_api::MLLogLevel::Info, + b"Pathfinder Demo\0".as_ptr() as *const _, + b"Initializing\0".as_ptr() as *const _, + ) + }; let tag = CString::new("Pathfinder Demo").unwrap(); let level = log::LevelFilter::Warn; @@ -97,7 +104,11 @@ pub extern "C" fn magicleap_pathfinder_demo_init(egl_display: EGLDisplay, egl_co info!("Initialized app"); let (sender, receiver) = flume::unbounded(); - Box::into_raw(Box::new(ImmersiveApp { sender, receiver, demo })) as *mut c_void + Box::into_raw(Box::new(ImmersiveApp { + sender, + receiver, + demo, + })) as *mut c_void } #[no_mangle] @@ -124,12 +135,17 @@ pub unsafe extern "C" fn magicleap_pathfinder_demo_run(app: *mut c_void) { } #[no_mangle] -pub unsafe extern "C" fn magicleap_pathfinder_demo_load(app: *mut c_void, svg_filename: *const c_char) { +pub unsafe extern "C" fn magicleap_pathfinder_demo_load( + app: *mut c_void, + svg_filename: *const c_char, +) { let app = app as *mut ImmersiveApp; if let Some(app) = app.as_mut() { let svg_filename = CStr::from_ptr(svg_filename).to_string_lossy().into_owned(); info!("Loading {}.", svg_filename); - let _ = app.sender.send(Event::OpenSVG(SVGPath::Resource(svg_filename))); + let _ = app + .sender + .send(Event::OpenSVG(SVGPath::Resource(svg_filename))); } } @@ -150,9 +166,13 @@ pub struct MagicLeapPathfinderRenderOptions { #[no_mangle] pub extern "C" fn magicleap_pathfinder_init() -> *mut c_void { - unsafe { c_api::MLLoggingLog(c_api::MLLogLevel::Info, - b"Pathfinder Demo\0".as_ptr() as *const _, - b"Initializing\0".as_ptr() as *const _) }; + unsafe { + c_api::MLLoggingLog( + c_api::MLLogLevel::Info, + b"Pathfinder Demo\0".as_ptr() as *const _, + b"Initializing\0".as_ptr() as *const _, + ) + }; let tag = CString::new("Pathfinder Demo").unwrap(); let level = log::LevelFilter::Info; @@ -175,12 +195,17 @@ pub extern "C" fn magicleap_pathfinder_init() -> *mut c_void { } #[no_mangle] -pub unsafe extern "C" fn magicleap_pathfinder_render(pf: *mut c_void, options: *const MagicLeapPathfinderRenderOptions) { +pub unsafe extern "C" fn magicleap_pathfinder_render( + pf: *mut c_void, + options: *const MagicLeapPathfinderRenderOptions, +) { let pf = pf as *mut MagicLeapPathfinder; if let (Some(pf), Some(options)) = (pf.as_mut(), options.as_ref()) { let resources = &pf.resources; - let svg_filename = CStr::from_ptr(options.svg_filename).to_string_lossy().into_owned(); + let svg_filename = CStr::from_ptr(options.svg_filename) + .to_string_lossy() + .into_owned(); let svg = pf.svgs.entry(svg_filename).or_insert_with(|| { let svg_filename = CStr::from_ptr(options.svg_filename).to_string_lossy(); let data = resources.slurp(&*svg_filename).unwrap(); @@ -191,35 +216,56 @@ pub unsafe extern "C" fn magicleap_pathfinder_render(pf: *mut c_void, options: * let mut width = 0; let mut height = 0; egl::query_surface(options.display, options.surface, egl::EGL_WIDTH, &mut width); - egl::query_surface(options.display, options.surface, egl::EGL_HEIGHT, &mut height); + egl::query_surface( + options.display, + options.surface, + egl::EGL_HEIGHT, + &mut height, + ); let size = vec2i(width, height); let viewport_origin = vec2i(options.viewport[0] as i32, options.viewport[1] as i32); let viewport_size = vec2i(options.viewport[2] as i32, options.viewport[3] as i32); let viewport = RectI::new(viewport_origin, viewport_size); - let bg_color = ColorF(F32x4::new(options.bg_color[0], options.bg_color[1], options.bg_color[2], options.bg_color[3])); + let bg_color = ColorF(F32x4::new( + options.bg_color[0], + options.bg_color[1], + options.bg_color[2], + options.bg_color[3], + )); - let renderer = pf.renderers.entry((options.display, options.surface)).or_insert_with(|| { - let mut fbo = 0; - gl::GetIntegerv(gl::DRAW_FRAMEBUFFER_BINDING, &mut fbo); - let device = GLDevice::new(GLVersion::GLES3, fbo as GLuint); - let dest_framebuffer = DestFramebuffer::Default { viewport, window_size: size }; - Renderer::new(device, resources, dest_framebuffer) - }); + let renderer = pf + .renderers + .entry((options.display, options.surface)) + .or_insert_with(|| { + let mut fbo = 0; + gl::GetIntegerv(gl::DRAW_FRAMEBUFFER_BINDING, &mut fbo); + let device = GLDevice::new(GLVersion::GLES3, fbo as GLuint); + let dest_framebuffer = DestFramebuffer::Default { + viewport, + window_size: size, + }; + Renderer::new(device, resources, dest_framebuffer) + }); renderer.set_main_framebuffer_size(size); renderer.device.bind_default_framebuffer(viewport); - renderer.device.clear(&ClearParams { color: Some(bg_color), ..ClearParams::default() }); + renderer.device.clear(&ClearParams { + color: Some(bg_color), + ..ClearParams::default() + }); renderer.disable_depth(); svg.scene.set_view_box(viewport.to_f32()); - let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 / - f32::max(svg.scene.bounds().size().x(), svg.scene.bounds().size().y()); + let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 + / f32::max(svg.scene.bounds().size().x(), svg.scene.bounds().size().y()); let transform = Transform2F::from_translation(svg.scene.bounds().size().scale(-0.5)) .post_mul(&Transform2F::from_scale(scale)) - .post_mul(&Transform2F::from_translation(viewport_size.to_f32().scale(0.5))); + .post_mul(&Transform2F::from_translation( + viewport_size.to_f32().scale(0.5), + )); let render_options = RenderOptions { transform: RenderTransform::Transform2D(transform), diff --git a/demo/magicleap/src/magicleap.rs b/demo/magicleap/src/magicleap.rs index 5342ca24..af2644bf 100644 --- a/demo/magicleap/src/magicleap.rs +++ b/demo/magicleap/src/magicleap.rs @@ -32,9 +32,9 @@ use crate::c_api::ML_RESULT_TIMEOUT; use crate::c_api::ML_VIRTUAL_CAMERA_COUNT; use egl; -use egl::EGL_NO_SURFACE; use egl::EGLContext; use egl::EGLDisplay; +use egl::EGL_NO_SURFACE; use gl; use gl::types::GLuint; @@ -53,12 +53,12 @@ use pathfinder_geometry::rect::RectI; use pathfinder_geometry::transform3d::Perspective; use pathfinder_geometry::transform3d::Transform4F; use pathfinder_geometry::util; -use pathfinder_geometry::vector::Vector2I; -use pathfinder_geometry::vector::Vector2F; use pathfinder_geometry::vector::vec2i; +use pathfinder_geometry::vector::Vector2F; +use pathfinder_geometry::vector::Vector2I; use pathfinder_gl::GLVersion; -use pathfinder_resources::ResourceLoader; use pathfinder_resources::fs::FilesystemResourceLoader; +use pathfinder_resources::ResourceLoader; use pathfinder_simd::default::F32x4; use rayon::ThreadPoolBuilder; @@ -99,19 +99,20 @@ impl Window for MagicLeapWindow { self.framebuffer_id } - fn adjust_thread_pool_settings(&self, thread_pool_builder: ThreadPoolBuilder) -> ThreadPoolBuilder { + fn adjust_thread_pool_settings( + &self, + thread_pool_builder: ThreadPoolBuilder, + ) -> ThreadPoolBuilder { thread_pool_builder.start_handler(|id| unsafe { init_scene_thread(id) }) } - fn create_user_event_id (&self) -> u32 { + fn create_user_event_id(&self) -> u32 { 0 } - fn push_user_event(_: u32, _: u32) { - } + fn push_user_event(_: u32, _: u32) {} - fn present_open_svg_dialog(&mut self) { - } + fn present_open_svg_dialog(&mut self) {} fn run_save_dialog(&self, _: &str) -> Result { Err(()) @@ -125,7 +126,10 @@ impl Window for MagicLeapWindow { self.begin_frame(); let eye = match view { View::Stereo(eye) if (eye as usize) < ML_VIRTUAL_CAMERA_COUNT => eye as usize, - _ => { debug!("Asked for unexpected view: {:?}", view); 0 } + _ => { + debug!("Asked for unexpected view: {:?}", view); + 0 + } }; debug!("Making {} current.", eye); let viewport = self.virtual_camera_array.viewport; @@ -135,9 +139,26 @@ impl Window for MagicLeapWindow { let layer_id = virtual_camera.virtual_camera_name as i32; unsafe { gl::BindFramebuffer(gl::FRAMEBUFFER, self.framebuffer_id); - gl::FramebufferTextureLayer(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, color_id, 0, layer_id); - gl::FramebufferTextureLayer(gl::FRAMEBUFFER, gl::DEPTH_ATTACHMENT, depth_id, 0, layer_id); - gl::Viewport(viewport.x as i32, viewport.y as i32, viewport.w as i32, viewport.h as i32); + gl::FramebufferTextureLayer( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + color_id, + 0, + layer_id, + ); + gl::FramebufferTextureLayer( + gl::FRAMEBUFFER, + gl::DEPTH_ATTACHMENT, + depth_id, + 0, + layer_id, + ); + gl::Viewport( + viewport.x as i32, + viewport.y as i32, + viewport.w as i32, + viewport.h as i32, + ); } debug!("Made {} current.", eye); } @@ -161,7 +182,7 @@ impl MagicLeapWindow { debug!("Creating MagicLeapWindow"); let mut framebuffer_id = 0; let graphics_options = MLGraphicsOptions::default(); - let mut graphics_client = unsafe { mem::zeroed() }; + let mut graphics_client = unsafe { mem::zeroed() }; let mut head_tracker = unsafe { mem::zeroed() }; let mut targets = unsafe { mem::zeroed() }; let virtual_camera_array = unsafe { mem::zeroed() }; @@ -175,7 +196,10 @@ impl MagicLeapWindow { MLHeadTrackingCreate(&mut head_tracker).unwrap(); MLGraphicsGetRenderTargets(graphics_client, &mut targets).unwrap(); } - let (max_width, max_height) = targets.buffers.iter().map(|buffer| buffer.color) + let (max_width, max_height) = targets + .buffers + .iter() + .map(|buffer| buffer.color) .chain(targets.buffers.iter().map(|buffer| buffer.depth)) .map(|target| (target.width as i32, target.height as i32)) .max() @@ -218,7 +242,12 @@ impl MagicLeapWindow { unsafe { gl::BindFramebuffer(gl::FRAMEBUFFER, self.framebuffer_id); MLGraphicsInitFrameParams(&mut params).unwrap(); - let mut result = MLGraphicsBeginFrame(self.graphics_client, ¶ms, &mut self.frame_handle, &mut self.virtual_camera_array); + let mut result = MLGraphicsBeginFrame( + self.graphics_client, + ¶ms, + &mut self.frame_handle, + &mut self.virtual_camera_array, + ); if result == ML_RESULT_TIMEOUT { info!("PF frame timeout"); let mut sleep = Duration::from_millis(1); @@ -227,7 +256,12 @@ impl MagicLeapWindow { sleep = (sleep * 2).min(max_sleep); info!("PF exponential backoff {}ms", sleep.as_millis()); thread::sleep(sleep); - result = MLGraphicsBeginFrame(self.graphics_client, ¶ms, &mut self.frame_handle, &mut self.virtual_camera_array); + result = MLGraphicsBeginFrame( + self.graphics_client, + ¶ms, + &mut self.frame_handle, + &mut self.virtual_camera_array, + ); } info!("PF frame finished timeout"); } @@ -236,21 +270,26 @@ impl MagicLeapWindow { let virtual_camera_array = &self.virtual_camera_array; let initial_camera = self.initial_camera_transform.get_or_insert_with(|| { let initial_offset = Transform4F::from_translation(0.0, 0.0, 1.0); - let mut camera = virtual_camera_array.virtual_cameras[0].transform; - for i in 1..virtual_camera_array.num_virtual_cameras { - let next = virtual_camera_array.virtual_cameras[i as usize].transform; - camera = camera.lerp(next, 1.0 / (i as f32 + 1.0)); - } - Transform4F::from(camera).post_mul(&initial_offset) + let mut camera = virtual_camera_array.virtual_cameras[0].transform; + for i in 1..virtual_camera_array.num_virtual_cameras { + let next = virtual_camera_array.virtual_cameras[i as usize].transform; + camera = camera.lerp(next, 1.0 / (i as f32 + 1.0)); + } + Transform4F::from(camera).post_mul(&initial_offset) }); let camera_transforms = (0..virtual_camera_array.num_virtual_cameras) .map(|i| { - let camera = &virtual_camera_array.virtual_cameras[i as usize]; + let camera = &virtual_camera_array.virtual_cameras[i as usize]; let projection = Transform4F::from(camera.projection); let size = RectI::from(virtual_camera_array.viewport).size(); let perspective = Perspective::new(&projection, size); - let modelview_to_eye = Transform4F::from(camera.transform).inverse().post_mul(initial_camera); - OcularTransform { perspective, modelview_to_eye } + let modelview_to_eye = Transform4F::from(camera.transform) + .inverse() + .post_mul(initial_camera); + OcularTransform { + perspective, + modelview_to_eye, + } }) .collect(); self.in_frame = true; @@ -266,7 +305,8 @@ impl MagicLeapWindow { gl::BindFramebuffer(gl::FRAMEBUFFER, 0); for i in 0..self.virtual_camera_array.num_virtual_cameras { let virtual_camera = &self.virtual_camera_array.virtual_cameras[i as usize]; - MLGraphicsSignalSyncObjectGL(self.graphics_client, virtual_camera.sync_object).unwrap(); + MLGraphicsSignalSyncObjectGL(self.graphics_client, virtual_camera.sync_object) + .unwrap(); } MLGraphicsEndFrame(self.graphics_client, self.frame_handle).unwrap(); } @@ -358,8 +398,7 @@ impl MLTransform { impl From for Transform4F { fn from(mat: MLTransform) -> Self { - Transform4F::from(mat.rotation) - .pre_mul(&Transform4F::from(mat.position)) + Transform4F::from(mat.rotation).pre_mul(&Transform4F::from(mat.position)) } } @@ -390,10 +429,9 @@ impl From for Transform4F { impl From for Transform4F { fn from(mat: MLMat4f) -> Self { let a = mat.matrix_colmajor; - Transform4F::row_major(a[0], a[4], a[8], a[12], - a[1], a[5], a[9], a[13], - a[2], a[6], a[10], a[14], - a[3], a[7], a[11], a[15]) + Transform4F::row_major( + a[0], a[4], a[8], a[12], a[1], a[5], a[9], a[13], a[2], a[6], a[10], a[14], a[3], a[7], + a[11], a[15], + ) } } - diff --git a/demo/magicleap/src/mocked_c_api.rs b/demo/magicleap/src/mocked_c_api.rs index 1a62f51b..53514118 100644 --- a/demo/magicleap/src/mocked_c_api.rs +++ b/demo/magicleap/src/mocked_c_api.rs @@ -28,7 +28,11 @@ use crate::c_api::MLSnapshotPtr; use crate::c_api::MLTransform; use std::os::raw::c_char; -pub unsafe fn MLGraphicsCreateClientGL(options: *const MLGraphicsOptions, gl_context: MLHandle, graphics_client : &mut MLHandle) -> MLResult { +pub unsafe fn MLGraphicsCreateClientGL( + options: *const MLGraphicsOptions, + gl_context: MLHandle, + graphics_client: &mut MLHandle, +) -> MLResult { unimplemented!() } @@ -40,7 +44,10 @@ pub unsafe fn MLHeadTrackingCreate(tracker: *mut MLHandle) -> MLResult { unimplemented!() } -pub unsafe fn MLHeadTrackingGetStaticData(head_tracker: MLHandle, data: *mut MLHeadTrackingStaticData) -> MLResult { +pub unsafe fn MLHeadTrackingGetStaticData( + head_tracker: MLHandle, + data: *mut MLHeadTrackingStaticData, +) -> MLResult { unimplemented!() } @@ -48,7 +55,11 @@ pub unsafe fn MLPerceptionGetSnapshot(snapshot: *mut MLSnapshotPtr) -> MLResult unimplemented!() } -pub unsafe fn MLSnapshotGetTransform(snapshot: MLSnapshotPtr, id: *const MLCoordinateFrameUID, transform: *mut MLTransform) -> MLResult { +pub unsafe fn MLSnapshotGetTransform( + snapshot: MLSnapshotPtr, + id: *const MLCoordinateFrameUID, + transform: *mut MLTransform, +) -> MLResult { unimplemented!() } @@ -60,11 +71,17 @@ pub unsafe fn MLLifecycleSetReadyIndication() -> MLResult { unimplemented!() } -pub unsafe fn MLGraphicsGetClipExtents(graphics_client: MLHandle, array: *mut MLGraphicsClipExtentsInfoArray) -> MLResult { +pub unsafe fn MLGraphicsGetClipExtents( + graphics_client: MLHandle, + array: *mut MLGraphicsClipExtentsInfoArray, +) -> MLResult { unimplemented!() } -pub unsafe fn MLGraphicsGetRenderTargets(graphics_client: MLHandle, targets: *mut MLGraphicsRenderTargetsInfo) -> MLResult { +pub unsafe fn MLGraphicsGetRenderTargets( + graphics_client: MLHandle, + targets: *mut MLGraphicsRenderTargetsInfo, +) -> MLResult { unimplemented!() } @@ -72,7 +89,12 @@ pub unsafe fn MLGraphicsInitFrameParams(params: *mut MLGraphicsFrameParams) -> M unimplemented!() } -pub unsafe fn MLGraphicsBeginFrame(graphics_client: MLHandle, params: *const MLGraphicsFrameParams, frame_handle: *mut MLHandle, virtual_camera_array: *mut MLGraphicsVirtualCameraInfoArray) -> MLResult { +pub unsafe fn MLGraphicsBeginFrame( + graphics_client: MLHandle, + params: *const MLGraphicsFrameParams, + frame_handle: *mut MLHandle, + virtual_camera_array: *mut MLGraphicsVirtualCameraInfoArray, +) -> MLResult { unimplemented!() } @@ -80,7 +102,10 @@ pub unsafe fn MLGraphicsEndFrame(graphics_client: MLHandle, frame_handle: MLHand unimplemented!() } -pub unsafe fn MLGraphicsSignalSyncObjectGL(graphics_client: MLHandle, sync_object: MLHandle) -> MLResult { +pub unsafe fn MLGraphicsSignalSyncObjectGL( + graphics_client: MLHandle, + sync_object: MLHandle, +) -> MLResult { unimplemented!() } @@ -95,4 +120,3 @@ pub unsafe fn MLLoggingLogLevelIsEnabled(lvl: MLLogLevel) -> bool { pub unsafe fn MLLoggingLog(lvl: MLLogLevel, tag: *const c_char, message: *const c_char) { unimplemented!() } - diff --git a/demo/native/src/main.rs b/demo/native/src/main.rs index 68c5ab34..7dcd8822 100644 --- a/demo/native/src/main.rs +++ b/demo/native/src/main.rs @@ -18,33 +18,33 @@ extern crate objc; use euclid::default::Size2D; use nfd::Response; -use pathfinder_demo::window::{Event, Keycode, DataPath, View, Window, WindowSize}; +use pathfinder_demo::window::{DataPath, Event, Keycode, View, Window, WindowSize}; use pathfinder_demo::{DemoApp, Options}; use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::{Vector2I, vec2i}; -use pathfinder_resources::ResourceLoader; +use pathfinder_geometry::vector::{vec2i, Vector2I}; use pathfinder_resources::fs::FilesystemResourceLoader; +use pathfinder_resources::ResourceLoader; use std::cell::Cell; use std::collections::VecDeque; use std::path::PathBuf; use std::sync::Mutex; -use surfman::{SurfaceAccess, SurfaceType, declare_surfman}; +use surfman::{declare_surfman, SurfaceAccess, SurfaceType}; +use winit::dpi::LogicalSize; use winit::{ControlFlow, ElementState, Event as WinitEvent, EventsLoop, EventsLoopProxy}; use winit::{MouseButton, VirtualKeyCode, Window as WinitWindow, WindowBuilder, WindowEvent}; -use winit::dpi::LogicalSize; -#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] -use gl::types::GLuint; #[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] use gl; #[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] -use surfman::{Connection, Context, ContextAttributeFlags, ContextAttributes}; -#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] -use surfman::{Device, GLVersion as SurfmanGLVersion}; +use gl::types::GLuint; #[cfg(all(target_os = "macos", not(feature = "pf-gl")))] use io_surface::IOSurfaceRef; #[cfg(all(target_os = "macos", not(feature = "pf-gl")))] use pathfinder_metal::MetalDevice; +#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] +use surfman::{Connection, Context, ContextAttributeFlags, ContextAttributes}; +#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] +use surfman::{Device, GLVersion as SurfmanGLVersion}; #[cfg(all(target_os = "macos", not(feature = "pf-gl")))] use surfman::{NativeDevice, SystemConnection, SystemDevice, SystemSurface}; @@ -138,7 +138,10 @@ struct EventQueue { #[derive(Clone)] enum CustomEvent { - User { message_type: u32, message_data: u32 }, + User { + message_type: u32, + message_data: u32, + }, OpenData(PathBuf), } @@ -155,15 +158,17 @@ impl Window for WindowImpl { #[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] fn gl_default_framebuffer(&self) -> GLuint { - self.device.context_surface_info(&self.context).unwrap().unwrap().framebuffer_object + self.device + .context_surface_info(&self.context) + .unwrap() + .unwrap() + .framebuffer_object } #[cfg(all(target_os = "macos", not(feature = "pf-gl")))] fn metal_device(&self) -> metal::Device { // FIXME(pcwalton): Remove once `surfman` upgrades `metal-rs` version. - unsafe { - std::mem::transmute(self.metal_device.0.clone()) - } + unsafe { std::mem::transmute(self.metal_device.0.clone()) } } #[cfg(all(target_os = "macos", not(feature = "pf-gl")))] @@ -172,7 +177,10 @@ impl Window for WindowImpl { } fn viewport(&self, view: View) -> RectI { - let WindowSize { logical_size, backing_scale_factor } = self.size(); + let WindowSize { + logical_size, + backing_scale_factor, + } = self.size(); let mut size = (logical_size.to_f32() * backing_scale_factor).to_i32(); let mut x_offset = 0; if let View::Stereo(index) = view { @@ -192,17 +200,24 @@ impl Window for WindowImpl { #[cfg(any(not(target_os = "macos"), feature = "pf-gl"))] fn present(&mut self, _: &mut GLDevice) { - let mut surface = self.device - .unbind_surface_from_context(&mut self.context) - .unwrap() - .unwrap(); - self.device.present_surface(&mut self.context, &mut surface).unwrap(); - self.device.bind_surface_to_context(&mut self.context, surface).unwrap(); + let mut surface = self + .device + .unbind_surface_from_context(&mut self.context) + .unwrap() + .unwrap(); + self.device + .present_surface(&mut self.context, &mut surface) + .unwrap(); + self.device + .bind_surface_to_context(&mut self.context, surface) + .unwrap(); } #[cfg(all(target_os = "macos", not(feature = "pf-gl")))] fn present(&mut self, metal_device: &mut MetalDevice) { - self.device.present_surface(&mut self.surface).expect("Failed to present surface!"); + self.device + .present_surface(&mut self.surface) + .expect("Failed to present surface!"); metal_device.swap_texture(self.device.native_surface(&self.surface).0); } @@ -214,7 +229,9 @@ impl Window for WindowImpl { if let Ok(Response::Okay(path)) = nfd::open_file_dialog(Some("svg,pdf"), None) { let mut event_queue = EVENT_QUEUE.lock().unwrap(); let event_queue = event_queue.as_mut().unwrap(); - event_queue.pending_custom_events.push_back(CustomEvent::OpenData(PathBuf::from(path))); + event_queue + .pending_custom_events + .push_back(CustomEvent::OpenData(PathBuf::from(path))); drop(event_queue.event_loop_proxy.wakeup()); } } @@ -235,10 +252,12 @@ impl Window for WindowImpl { fn push_user_event(message_type: u32, message_data: u32) { let mut event_queue = EVENT_QUEUE.lock().unwrap(); let event_queue = event_queue.as_mut().unwrap(); - event_queue.pending_custom_events.push_back(CustomEvent::User { - message_type, - message_data, - }); + event_queue + .pending_custom_events + .push_back(CustomEvent::User { + message_type, + message_data, + }); drop(event_queue.event_loop_proxy.wakeup()); } } @@ -249,14 +268,17 @@ impl WindowImpl { let event_loop = EventsLoop::new(); let window_size = Size2D::new(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT); let logical_size = LogicalSize::new(window_size.width as f64, window_size.height as f64); - let window = WindowBuilder::new().with_title("Pathfinder Demo") - .with_dimensions(logical_size) - .build(&event_loop) - .unwrap(); + let window = WindowBuilder::new() + .with_title("Pathfinder Demo") + .with_dimensions(logical_size) + .build(&event_loop) + .unwrap(); window.show(); let connection = Connection::from_winit_window(&window).unwrap(); - let native_widget = connection.create_native_widget_from_winit_window(&window).unwrap(); + let native_widget = connection + .create_native_widget_from_winit_window(&window) + .unwrap(); let adapter = if options.high_performance_gpu { connection.create_hardware_adapter().unwrap() @@ -270,13 +292,18 @@ impl WindowImpl { version: SurfmanGLVersion::new(3, 0), flags: ContextAttributeFlags::ALPHA, }; - let context_descriptor = device.create_context_descriptor(&context_attributes).unwrap(); + let context_descriptor = device + .create_context_descriptor(&context_attributes) + .unwrap(); let surface_type = SurfaceType::Widget { native_widget }; let mut context = device.create_context(&context_descriptor).unwrap(); - let surface = device.create_surface(&context, SurfaceAccess::GPUOnly, surface_type) - .unwrap(); - device.bind_surface_to_context(&mut context, surface).unwrap(); + let surface = device + .create_surface(&context, SurfaceAccess::GPUOnly, surface_type) + .unwrap(); + device + .bind_surface_to_context(&mut context, surface) + .unwrap(); device.make_context_current(&context).unwrap(); gl::load_with(|symbol_name| device.get_proc_address(&context, symbol_name)); @@ -307,14 +334,17 @@ impl WindowImpl { let event_loop = EventsLoop::new(); let window_size = Size2D::new(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT); let logical_size = LogicalSize::new(window_size.width as f64, window_size.height as f64); - let window = WindowBuilder::new().with_title("Pathfinder Demo") - .with_dimensions(logical_size) - .build(&event_loop) - .unwrap(); + let window = WindowBuilder::new() + .with_title("Pathfinder Demo") + .with_dimensions(logical_size) + .build(&event_loop) + .unwrap(); window.show(); let connection = SystemConnection::from_winit_window(&window).unwrap(); - let native_widget = connection.create_native_widget_from_winit_window(&window).unwrap(); + let native_widget = connection + .create_native_widget_from_winit_window(&window) + .unwrap(); let adapter = if options.high_performance_gpu { connection.create_hardware_adapter().unwrap() @@ -326,7 +356,9 @@ impl WindowImpl { let native_device = device.native_device(); let surface_type = SurfaceType::Widget { native_widget }; - let surface = device.create_surface(SurfaceAccess::GPUOnly, surface_type).unwrap(); + let surface = device + .create_surface(SurfaceAccess::GPUOnly, surface_type) + .unwrap(); let resource_loader = FilesystemResourceLoader::locate(); @@ -350,11 +382,16 @@ impl WindowImpl { } } - fn window(&self) -> &WinitWindow { &self.window } + fn window(&self) -> &WinitWindow { + &self.window + } fn size(&self) -> WindowSize { let window = self.window(); - let (monitor, size) = (window.get_current_monitor(), window.get_inner_size().unwrap()); + let (monitor, size) = ( + window.get_current_monitor(), + window.get_inner_size().unwrap(), + ); WindowSize { logical_size: vec2i(size.width as i32, size.height as i32), @@ -370,18 +407,13 @@ impl WindowImpl { let pending_events = &mut self.pending_events; self.event_loop.run_forever(|winit_event| { //println!("blocking {:?}", winit_event); - match convert_winit_event(winit_event, - window, - mouse_position, - mouse_down) { + match convert_winit_event(winit_event, window, mouse_position, mouse_down) { Some(event) => { //println!("handled"); pending_events.push_back(event); ControlFlow::Break } - None => { - ControlFlow::Continue - } + None => ControlFlow::Continue, } }); } @@ -397,10 +429,9 @@ impl WindowImpl { let pending_events = &mut self.pending_events; self.event_loop.poll_events(|winit_event| { //println!("nonblocking {:?}", winit_event); - if let Some(event) = convert_winit_event(winit_event, - window, - mouse_position, - mouse_down) { + if let Some(event) = + convert_winit_event(winit_event, window, mouse_position, mouse_down) + { //println!("handled"); pending_events.push_back(event); } @@ -410,87 +441,93 @@ impl WindowImpl { } } -fn convert_winit_event(winit_event: WinitEvent, - window: &WinitWindow, - mouse_position: &mut Vector2I, - mouse_down: &mut bool) - -> Option { +fn convert_winit_event( + winit_event: WinitEvent, + window: &WinitWindow, + mouse_position: &mut Vector2I, + mouse_down: &mut bool, +) -> Option { match winit_event { WinitEvent::Awakened => { let mut event_queue = EVENT_QUEUE.lock().unwrap(); let event_queue = event_queue.as_mut().unwrap(); - match event_queue.pending_custom_events - .pop_front() - .expect("`Awakened` with no pending custom event!") { - CustomEvent::OpenData(data_path) => Some(Event::OpenData(DataPath::Path(data_path))), - CustomEvent::User { message_data, message_type } => { - Some(Event::User { message_data, message_type }) + match event_queue + .pending_custom_events + .pop_front() + .expect("`Awakened` with no pending custom event!") + { + CustomEvent::OpenData(data_path) => { + Some(Event::OpenData(DataPath::Path(data_path))) } + CustomEvent::User { + message_data, + message_type, + } => Some(Event::User { + message_data, + message_type, + }), } } - WinitEvent::WindowEvent { event: window_event, .. } => { - match window_event { - WindowEvent::MouseInput { - state: ElementState::Pressed, - button: MouseButton::Left, - .. - } => { - *mouse_down = true; - Some(Event::MouseDown(*mouse_position)) + WinitEvent::WindowEvent { + event: window_event, + .. + } => match window_event { + WindowEvent::MouseInput { + state: ElementState::Pressed, + button: MouseButton::Left, + .. + } => { + *mouse_down = true; + Some(Event::MouseDown(*mouse_position)) + } + WindowEvent::MouseInput { + state: ElementState::Released, + button: MouseButton::Left, + .. + } => { + *mouse_down = false; + None + } + WindowEvent::CursorMoved { position, .. } => { + *mouse_position = vec2i(position.x as i32, position.y as i32); + if *mouse_down { + Some(Event::MouseDragged(*mouse_position)) + } else { + Some(Event::MouseMoved(*mouse_position)) } - WindowEvent::MouseInput { - state: ElementState::Released, - button: MouseButton::Left, - .. - } => { - *mouse_down = false; - None - } - WindowEvent::CursorMoved { position, .. } => { - *mouse_position = vec2i(position.x as i32, position.y as i32); - if *mouse_down { - Some(Event::MouseDragged(*mouse_position)) - } else { - Some(Event::MouseMoved(*mouse_position)) + } + WindowEvent::KeyboardInput { input, .. } => input + .virtual_keycode + .and_then(|virtual_keycode| match virtual_keycode { + VirtualKeyCode::Escape => Some(Keycode::Escape), + VirtualKeyCode::Tab => Some(Keycode::Tab), + virtual_keycode => { + let vk = virtual_keycode as u32; + let vk_a = VirtualKeyCode::A as u32; + let vk_z = VirtualKeyCode::Z as u32; + if vk >= vk_a && vk <= vk_z { + let character = ((vk - vk_a) + 'A' as u32) as u8; + Some(Keycode::Alphanumeric(character)) + } else { + None + } } - } - WindowEvent::KeyboardInput { input, .. } => { - input.virtual_keycode.and_then(|virtual_keycode| { - match virtual_keycode { - VirtualKeyCode::Escape => Some(Keycode::Escape), - VirtualKeyCode::Tab => Some(Keycode::Tab), - virtual_keycode => { - let vk = virtual_keycode as u32; - let vk_a = VirtualKeyCode::A as u32; - let vk_z = VirtualKeyCode::Z as u32; - if vk >= vk_a && vk <= vk_z { - let character = ((vk - vk_a) + 'A' as u32) as u8; - Some(Keycode::Alphanumeric(character)) - } else { - None - } - } - } - }).map(|keycode| { - match input.state { - ElementState::Pressed => Event::KeyDown(keycode), - ElementState::Released => Event::KeyUp(keycode), - } - }) - } - WindowEvent::CloseRequested => Some(Event::Quit), - WindowEvent::Resized(new_size) => { - let logical_size = vec2i(new_size.width as i32, new_size.height as i32); - let backing_scale_factor = - window.get_current_monitor().get_hidpi_factor() as f32; - Some(Event::WindowResized(WindowSize { - logical_size, - backing_scale_factor, - })) - } - _ => None, + }) + .map(|keycode| match input.state { + ElementState::Pressed => Event::KeyDown(keycode), + ElementState::Released => Event::KeyUp(keycode), + }), + WindowEvent::CloseRequested => Some(Event::Quit), + WindowEvent::Resized(new_size) => { + let logical_size = vec2i(new_size.width as i32, new_size.height as i32); + let backing_scale_factor = window.get_current_monitor().get_hidpi_factor() as f32; + Some(Event::WindowResized(WindowSize { + logical_size, + backing_scale_factor, + })) } - } + _ => None, + }, _ => None, } -} \ No newline at end of file +} diff --git a/examples/canvas_glutin_minimal/src/main.rs b/examples/canvas_glutin_minimal/src/main.rs index 072b4c0d..f3cd1175 100644 --- a/examples/canvas_glutin_minimal/src/main.rs +++ b/examples/canvas_glutin_minimal/src/main.rs @@ -11,21 +11,21 @@ //! Demonstrates how to use the Pathfinder canvas API with `glutin`. use glutin::dpi::PhysicalSize; -use glutin::{ContextBuilder, GlProfile, GlRequest}; -use glutin::event_loop::{ControlFlow, EventLoop}; use glutin::event::{Event, KeyboardInput, VirtualKeyCode, WindowEvent}; +use glutin::event_loop::{ControlFlow, EventLoop}; use glutin::window::WindowBuilder; +use glutin::{ContextBuilder, GlProfile, GlRequest}; use pathfinder_canvas::{Canvas, CanvasFontContext, Path2D}; use pathfinder_color::ColorF; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::{vec2f, vec2i}; use pathfinder_gl::{GLDevice, GLVersion}; -use pathfinder_resources::embedded::EmbeddedResourceLoader; use pathfinder_renderer::concurrent::rayon::RayonExecutor; use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; -use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererMode, RendererOptions}; +use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::options::BuildOptions; +use pathfinder_resources::embedded::EmbeddedResourceLoader; fn main() { // Calculate the right logical size of the window. @@ -34,14 +34,16 @@ fn main() { let physical_window_size = PhysicalSize::new(window_size.x() as f64, window_size.y() as f64); // Open a window. - let window_builder = WindowBuilder::new().with_title("Minimal example") - .with_inner_size(physical_window_size); + let window_builder = WindowBuilder::new() + .with_title("Minimal example") + .with_inner_size(physical_window_size); // Create an OpenGL 3.x context for Pathfinder to use. - let gl_context = ContextBuilder::new().with_gl(GlRequest::Latest) - .with_gl_profile(GlProfile::Core) - .build_windowed(window_builder, &event_loop) - .unwrap(); + let gl_context = ContextBuilder::new() + .with_gl(GlRequest::Latest) + .with_gl_profile(GlProfile::Core) + .build_windowed(window_builder, &event_loop) + .unwrap(); // Load OpenGL, and make the context current. let gl_context = unsafe { gl_context.make_current().unwrap() }; @@ -79,28 +81,38 @@ fn main() { canvas.stroke_path(path); // Render the canvas to screen. - let mut scene = SceneProxy::from_scene(canvas.into_canvas().into_scene(), - renderer.mode().level, - RayonExecutor); + let mut scene = SceneProxy::from_scene( + canvas.into_canvas().into_scene(), + renderer.mode().level, + RayonExecutor, + ); scene.build_and_render(&mut renderer, BuildOptions::default()); gl_context.swap_buffers().unwrap(); // Wait for a keypress. event_loop.run(move |event, _, control_flow| { match event { - Event::WindowEvent { event: WindowEvent::CloseRequested, .. } | Event::WindowEvent { - event: WindowEvent::KeyboardInput { - input: KeyboardInput { virtual_keycode: Some(VirtualKeyCode::Escape), .. }, - .. - }, + event: WindowEvent::CloseRequested, + .. + } + | Event::WindowEvent { + event: + WindowEvent::KeyboardInput { + input: + KeyboardInput { + virtual_keycode: Some(VirtualKeyCode::Escape), + .. + }, + .. + }, .. } => { *control_flow = ControlFlow::Exit; - }, + } _ => { *control_flow = ControlFlow::Wait; - }, + } }; }) } diff --git a/examples/canvas_metal_minimal/src/main.rs b/examples/canvas_metal_minimal/src/main.rs index dd3bb712..ee25cdc8 100644 --- a/examples/canvas_metal_minimal/src/main.rs +++ b/examples/canvas_metal_minimal/src/main.rs @@ -12,8 +12,8 @@ use foreign_types::ForeignTypeRef; use metal::{CAMetalLayer, CoreAnimationLayerRef}; use pathfinder_canvas::{Canvas, CanvasFontContext, Path2D}; use pathfinder_color::ColorF; -use pathfinder_geometry::vector::{vec2f, vec2i}; use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, vec2i}; use pathfinder_metal::MetalDevice; use pathfinder_renderer::concurrent::rayon::RayonExecutor; use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; @@ -34,10 +34,15 @@ fn main() { // Open a window. let window_size = vec2i(640, 480); - let window = video.window("Minimal example", window_size.x() as u32, window_size.y() as u32) - .opengl() - .build() - .unwrap(); + let window = video + .window( + "Minimal example", + window_size.x() as u32, + window_size.y() as u32, + ) + .opengl() + .build() + .unwrap(); // Create a Metal context. let canvas = window.into_canvas().present_vsync().build().unwrap(); @@ -48,9 +53,7 @@ fn main() { let drawable = metal_layer.next_drawable().unwrap(); // Create a Pathfinder renderer. - let device = unsafe { - MetalDevice::new(metal_device, drawable.clone()) - }; + let device = unsafe { MetalDevice::new(metal_device, drawable.clone()) }; let mode = RendererMode::default_for_device(&device); let options = RendererOptions { dest: DestFramebuffer::full_window(window_size), @@ -81,9 +84,11 @@ fn main() { canvas.stroke_path(path); // Render the canvas to screen. - let mut scene = SceneProxy::from_scene(canvas.into_canvas().into_scene(), - renderer.mode().level, - RayonExecutor); + let mut scene = SceneProxy::from_scene( + canvas.into_canvas().into_scene(), + renderer.mode().level, + RayonExecutor, + ); scene.build_and_render(&mut renderer, BuildOptions::default()); renderer.device().present_drawable(drawable); @@ -91,7 +96,11 @@ fn main() { let mut event_pump = sdl_context.event_pump().unwrap(); loop { match event_pump.wait_event() { - Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => return, + Event::Quit { .. } + | Event::KeyDown { + keycode: Some(Keycode::Escape), + .. + } => return, _ => {} } } diff --git a/examples/canvas_minimal/src/main.rs b/examples/canvas_minimal/src/main.rs index 3f294068..686bdc95 100644 --- a/examples/canvas_minimal/src/main.rs +++ b/examples/canvas_minimal/src/main.rs @@ -20,7 +20,9 @@ use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererMode, RendererO use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::options::BuildOptions; use pathfinder_resources::embedded::EmbeddedResourceLoader; -use surfman::{Connection, ContextAttributeFlags, ContextAttributes, GLVersion as SurfmanGLVersion}; +use surfman::{ + Connection, ContextAttributeFlags, ContextAttributes, GLVersion as SurfmanGLVersion, +}; use surfman::{SurfaceAccess, SurfaceType}; use winit::dpi::LogicalSize; use winit::{ControlFlow, Event, EventsLoop, WindowBuilder, WindowEvent}; @@ -30,16 +32,19 @@ fn main() { let mut event_loop = EventsLoop::new(); let window_size = Size2D::new(640, 480); let logical_size = LogicalSize::new(window_size.width as f64, window_size.height as f64); - let window = WindowBuilder::new().with_title("Minimal example") - .with_dimensions(logical_size) - .build(&event_loop) - .unwrap(); + let window = WindowBuilder::new() + .with_title("Minimal example") + .with_dimensions(logical_size) + .build(&event_loop) + .unwrap(); window.show(); // Create a `surfman` device. On a multi-GPU system, we'll request the low-power integrated // GPU. let connection = Connection::from_winit_window(&window).unwrap(); - let native_widget = connection.create_native_widget_from_winit_window(&window).unwrap(); + let native_widget = connection + .create_native_widget_from_winit_window(&window) + .unwrap(); let adapter = connection.create_low_power_adapter().unwrap(); let mut device = connection.create_device(&adapter).unwrap(); @@ -48,14 +53,19 @@ fn main() { version: SurfmanGLVersion::new(3, 0), flags: ContextAttributeFlags::ALPHA, }; - let context_descriptor = device.create_context_descriptor(&context_attributes).unwrap(); + let context_descriptor = device + .create_context_descriptor(&context_attributes) + .unwrap(); // Make the OpenGL context via `surfman`, and load OpenGL functions. let surface_type = SurfaceType::Widget { native_widget }; let mut context = device.create_context(&context_descriptor).unwrap(); - let surface = device.create_surface(&context, SurfaceAccess::GPUOnly, surface_type) - .unwrap(); - device.bind_surface_to_context(&mut context, surface).unwrap(); + let surface = device + .create_surface(&context, SurfaceAccess::GPUOnly, surface_type) + .unwrap(); + device + .bind_surface_to_context(&mut context, surface) + .unwrap(); device.make_context_current(&context).unwrap(); gl::load_with(|symbol_name| device.get_proc_address(&context, symbol_name)); @@ -65,10 +75,11 @@ fn main() { let framebuffer_size = vec2i(physical_size.width as i32, physical_size.height as i32); // Create a Pathfinder GL device. - let default_framebuffer = device.context_surface_info(&context) - .unwrap() - .unwrap() - .framebuffer_object; + let default_framebuffer = device + .context_surface_info(&context) + .unwrap() + .unwrap() + .framebuffer_object; let pathfinder_device = GLDevice::new(GLVersion::GL3, default_framebuffer); // Create a Pathfinder renderer. @@ -87,17 +98,27 @@ fn main() { event_loop.run_forever(|event| { let mut should_render = is_first_render; match event { - Event::WindowEvent { event: WindowEvent::CloseRequested, .. } | - Event::WindowEvent { event: WindowEvent::KeyboardInput { .. }, .. } => return ControlFlow::Break, - Event::WindowEvent { event: WindowEvent::Refresh, .. } => { + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } + | Event::WindowEvent { + event: WindowEvent::KeyboardInput { .. }, + .. + } => return ControlFlow::Break, + Event::WindowEvent { + event: WindowEvent::Refresh, + .. + } => { should_render = true; } - _ => {}, + _ => {} } if should_render { // Make a canvas. We're going to draw a house. - let mut canvas = Canvas::new(framebuffer_size.to_f32()).get_context_2d(font_context.clone()); + let mut canvas = + Canvas::new(framebuffer_size.to_f32()).get_context_2d(font_context.clone()); // Set line width. canvas.set_line_width(10.0); @@ -117,15 +138,22 @@ fn main() { canvas.stroke_path(path); // Render the canvas to screen. - let mut scene = SceneProxy::from_scene(canvas.into_canvas().into_scene(), - renderer.mode().level, - RayonExecutor); + let mut scene = SceneProxy::from_scene( + canvas.into_canvas().into_scene(), + renderer.mode().level, + RayonExecutor, + ); scene.build_and_render(&mut renderer, BuildOptions::default()); // Present the surface. - let mut surface = device.unbind_surface_from_context(&mut context).unwrap().unwrap(); + let mut surface = device + .unbind_surface_from_context(&mut context) + .unwrap() + .unwrap(); device.present_surface(&mut context, &mut surface).unwrap(); - device.bind_surface_to_context(&mut context, surface).unwrap(); + device + .bind_surface_to_context(&mut context, surface) + .unwrap(); } is_first_render = false; diff --git a/examples/canvas_moire/src/main.rs b/examples/canvas_moire/src/main.rs index a1d24ed2..22859bb8 100644 --- a/examples/canvas_moire/src/main.rs +++ b/examples/canvas_moire/src/main.rs @@ -11,7 +11,7 @@ use euclid::default::Size2D; use pathfinder_canvas::{Canvas, CanvasFontContext, CanvasRenderingContext2D, FillStyle, Path2D}; use pathfinder_color::{ColorF, ColorU}; -use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2f, vec2i}; +use pathfinder_geometry::vector::{vec2f, vec2i, Vector2F, Vector2I}; use pathfinder_gl::{GLDevice, GLVersion}; use pathfinder_renderer::concurrent::rayon::RayonExecutor; use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; @@ -19,9 +19,11 @@ use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererMode, RendererO use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::options::BuildOptions; use pathfinder_resources::embedded::EmbeddedResourceLoader; -use std::f32::consts::PI; use std::f32; -use surfman::{Connection, ContextAttributeFlags, ContextAttributes, GLVersion as SurfmanGLVersion}; +use std::f32::consts::PI; +use surfman::{ + Connection, ContextAttributeFlags, ContextAttributes, GLVersion as SurfmanGLVersion, +}; use surfman::{SurfaceAccess, SurfaceType}; use winit::dpi::LogicalSize; use winit::{Event, EventsLoop, WindowBuilder, WindowEvent}; @@ -43,16 +45,19 @@ fn main() { let mut event_loop = EventsLoop::new(); let window_size = Size2D::new(1067, 800); let logical_size = LogicalSize::new(window_size.width as f64, window_size.height as f64); - let window = WindowBuilder::new().with_title("Moire example") - .with_dimensions(logical_size) - .build(&event_loop) - .unwrap(); + let window = WindowBuilder::new() + .with_title("Moire example") + .with_dimensions(logical_size) + .build(&event_loop) + .unwrap(); window.show(); // Create a `surfman` device. On a multi-GPU system, we'll request the low-power integrated // GPU. let connection = Connection::from_winit_window(&window).unwrap(); - let native_widget = connection.create_native_widget_from_winit_window(&window).unwrap(); + let native_widget = connection + .create_native_widget_from_winit_window(&window) + .unwrap(); let adapter = connection.create_low_power_adapter().unwrap(); let mut device = connection.create_device(&adapter).unwrap(); @@ -61,14 +66,19 @@ fn main() { version: SurfmanGLVersion::new(3, 0), flags: ContextAttributeFlags::ALPHA, }; - let context_descriptor = device.create_context_descriptor(&context_attributes).unwrap(); + let context_descriptor = device + .create_context_descriptor(&context_attributes) + .unwrap(); // Make the OpenGL context via `surfman`, and load OpenGL functions. let surface_type = SurfaceType::Widget { native_widget }; let mut gl_context = device.create_context(&context_descriptor).unwrap(); - let surface = device.create_surface(&gl_context, SurfaceAccess::GPUOnly, surface_type) - .unwrap(); - device.bind_surface_to_context(&mut gl_context, surface).unwrap(); + let surface = device + .create_surface(&gl_context, SurfaceAccess::GPUOnly, surface_type) + .unwrap(); + device + .bind_surface_to_context(&mut gl_context, surface) + .unwrap(); device.make_context_current(&gl_context).unwrap(); gl::load_with(|symbol_name| device.get_proc_address(&gl_context, symbol_name)); @@ -78,10 +88,11 @@ fn main() { let framebuffer_size = vec2i(physical_size.width as i32, physical_size.height as i32); // Create a Pathfinder GL device. - let default_framebuffer = device.context_surface_info(&gl_context) - .unwrap() - .unwrap() - .framebuffer_object; + let default_framebuffer = device + .context_surface_info(&gl_context) + .unwrap() + .unwrap() + .framebuffer_object; let pathfinder_device = GLDevice::new(GLVersion::GL3, default_framebuffer); // Create our renderers. @@ -101,16 +112,27 @@ fn main() { moire_renderer.render(); // Present the rendered canvas via `surfman`. - let mut surface = device.unbind_surface_from_context(&mut gl_context).unwrap().unwrap(); - device.present_surface(&mut gl_context, &mut surface).unwrap(); - device.bind_surface_to_context(&mut gl_context, surface).unwrap(); + let mut surface = device + .unbind_surface_from_context(&mut gl_context) + .unwrap() + .unwrap(); + device + .present_surface(&mut gl_context, &mut surface) + .unwrap(); + device + .bind_surface_to_context(&mut gl_context, surface) + .unwrap(); - event_loop.poll_events(|event| { - match event { - Event::WindowEvent { event: WindowEvent::CloseRequested, .. } | - Event::WindowEvent { event: WindowEvent::KeyboardInput { .. }, .. } => exit = true, - _ => {} + event_loop.poll_events(|event| match event { + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. } + | Event::WindowEvent { + event: WindowEvent::KeyboardInput { .. }, + .. + } => exit = true, + _ => {} }); } } @@ -127,8 +149,11 @@ struct MoireRenderer { } impl MoireRenderer { - fn new(renderer: Renderer, window_size: Vector2I, drawable_size: Vector2I) - -> MoireRenderer { + fn new( + renderer: Renderer, + window_size: Vector2I, + drawable_size: Vector2I, + ) -> MoireRenderer { let level = renderer.mode().level; MoireRenderer { renderer, @@ -159,7 +184,7 @@ impl MoireRenderer { self.renderer.options_mut().background_color = Some(background_color); // Make a canvas. - let mut canvas = + let mut canvas = Canvas::new(self.drawable_size.to_f32()).get_context_2d(self.font_context.clone()); canvas.set_line_width(CIRCLE_THICKNESS * self.device_pixel_ratio); canvas.set_stroke_style(FillStyle::Color(foreground_color.to_u8())); @@ -171,7 +196,8 @@ impl MoireRenderer { // Build and render scene. self.scene.replace_scene(canvas.into_canvas().into_scene()); - self.scene.build_and_render(&mut self.renderer, BuildOptions::default()); + self.scene + .build_and_render(&mut self.renderer, BuildOptions::default()); self.frame += 1; } diff --git a/examples/canvas_nanovg/Cargo.toml b/examples/canvas_nanovg/Cargo.toml index 3127b91c..995580ae 100644 --- a/examples/canvas_nanovg/Cargo.toml +++ b/examples/canvas_nanovg/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayvec = "0.5" -font-kit = "0.6" +font-kit = "0.13" gl = "0.14" [dependencies.euclid] diff --git a/examples/canvas_nanovg/src/main.rs b/examples/canvas_nanovg/src/main.rs index 0d9808f3..2d061162 100644 --- a/examples/canvas_nanovg/src/main.rs +++ b/examples/canvas_nanovg/src/main.rs @@ -15,7 +15,7 @@ use font_kit::sources::mem::MemSource; use image; use pathfinder_canvas::{Canvas, CanvasFontContext, CanvasRenderingContext2D, LineJoin, Path2D}; use pathfinder_canvas::{TextAlign, TextBaseline, TextMetrics}; -use pathfinder_color::{ColorF, ColorU, rgbau, rgbf, rgbu}; +use pathfinder_color::{rgbau, rgbf, rgbu, ColorF, ColorU}; use pathfinder_content::fill::FillRule; use pathfinder_content::gradient::Gradient; use pathfinder_content::outline::ArcDirection; @@ -26,27 +26,33 @@ use pathfinder_geometry::line_segment::LineSegment2F; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::transform2d::Transform2F; use pathfinder_geometry::util; -use pathfinder_geometry::vector::{Vector2F, vec2f, vec2i}; +use pathfinder_geometry::vector::{vec2f, vec2i, Vector2F}; use pathfinder_gl::{GLDevice, GLVersion}; use pathfinder_renderer::concurrent::rayon::RayonExecutor; use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererMode, RendererOptions}; use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::options::BuildOptions; -use pathfinder_resources::ResourceLoader; use pathfinder_resources::fs::FilesystemResourceLoader; +use pathfinder_resources::ResourceLoader; use pathfinder_simd::default::F32x2; use std::collections::VecDeque; use std::f32::consts::PI; use std::iter; use std::sync::Arc; use std::time::Instant; -use surfman::{Connection, ContextAttributeFlags, ContextAttributes, GLVersion as SurfmanGLVersion}; +use surfman::{ + Connection, ContextAttributeFlags, ContextAttributes, GLVersion as SurfmanGLVersion, +}; use surfman::{SurfaceAccess, SurfaceType}; use winit::dpi::LogicalSize; use winit::platform::run_return::EventLoopExtRunReturn; -use winit::{event::{Event, WindowEvent, KeyboardInput, VirtualKeyCode}, window::WindowBuilder, event_loop::{EventLoop, ControlFlow}}; +use winit::{ + event::{Event, KeyboardInput, VirtualKeyCode, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, +}; #[cfg(not(windows))] use jemallocator; @@ -66,38 +72,53 @@ const GRAPH_HEIGHT: f32 = 35.0; const GRAPH_HISTORY_COUNT: usize = 100; static FONT_NAME_REGULAR: &'static str = "Roboto-Regular"; -static FONT_NAME_BOLD: &'static str = "Roboto-Bold"; -static FONT_NAME_EMOJI: &'static str = "NotoEmoji"; +static FONT_NAME_BOLD: &'static str = "Roboto-Bold"; +static FONT_NAME_EMOJI: &'static str = "NotoEmoji"; static PARAGRAPH_TEXT: &'static str = "This is a longer chunk of text. -I would have used lorem ipsum, but she was busy jumping over the lazy dog with the fox and all \ -the men who came to the aid of the party. 🎉"; +I would have used lorem ipsum, but she was busy jumping over the lazy dog with the fox and all the \ + men who came to the aid of the party. 🎉"; -static HOVER_TEXT: &'static str = "Hover your mouse over the text to see the calculated caret \ -position."; +static HOVER_TEXT: &'static str = + "Hover your mouse over the text to see the calculated caret position."; -fn render_demo(context: &mut CanvasRenderingContext2D, - mouse_position: Vector2F, - window_size: Vector2F, - time: f32, - hidpi_factor: f32, - data: &DemoData) { - draw_eyes(context, - RectF::new(vec2f(window_size.x() - 250.0, 50.0), vec2f(150.0, 100.0)), - mouse_position, - time); - draw_paragraph(context, vec2f(window_size.x() - 450.0, 50.0), 150.0, mouse_position); - draw_graph(context, - RectF::new(window_size * vec2f(0.0, 0.5), window_size * vec2f(1.0, 0.5)), - time); - draw_color_wheel(context, - RectF::new(window_size - vec2f(300.0, 300.0), vec2f(250.0, 250.0)), - time, - hidpi_factor); - draw_lines(context, - RectF::new(vec2f(120.0, window_size.y() - 50.0), vec2f(600.0, 50.0)), - time); +fn render_demo( + context: &mut CanvasRenderingContext2D, + mouse_position: Vector2F, + window_size: Vector2F, + time: f32, + hidpi_factor: f32, + data: &DemoData, +) { + draw_eyes( + context, + RectF::new(vec2f(window_size.x() - 250.0, 50.0), vec2f(150.0, 100.0)), + mouse_position, + time, + ); + draw_paragraph( + context, + vec2f(window_size.x() - 450.0, 50.0), + 150.0, + mouse_position, + ); + draw_graph( + context, + RectF::new(window_size * vec2f(0.0, 0.5), window_size * vec2f(1.0, 0.5)), + time, + ); + draw_color_wheel( + context, + RectF::new(window_size - vec2f(300.0, 300.0), vec2f(250.0, 250.0)), + time, + hidpi_factor, + ); + draw_lines( + context, + RectF::new(vec2f(120.0, window_size.y() - 50.0), vec2f(600.0, 50.0)), + time, + ); draw_widths(context, vec2f(10.0, 50.0), 30.0); draw_caps(context, RectF::new(vec2f(10.0, 300.0), vec2f(30.0, 40.0))); draw_clip(context, vec2f(50.0, window_size.y() - 80.0), time); @@ -105,12 +126,19 @@ fn render_demo(context: &mut CanvasRenderingContext2D, context.save(); // Draw widgets. - draw_window(context, - "Widgets & Stuff", - RectF::new(vec2f(50.0, 50.0), vec2f(300.0, 400.0)), - hidpi_factor); + draw_window( + context, + "Widgets & Stuff", + RectF::new(vec2f(50.0, 50.0), vec2f(300.0, 400.0)), + hidpi_factor, + ); let mut position = vec2f(60.0, 95.0); - draw_search_box(context, "Search", RectF::new(position, vec2f(280.0, 25.0)), hidpi_factor); + draw_search_box( + context, + "Search", + RectF::new(position, vec2f(280.0, 25.0)), + hidpi_factor, + ); position += vec2f(0.0, 40.0); draw_dropdown(context, "Effects", RectF::new(position, vec2f(280.0, 28.0))); let popup_position = position + vec2f(0.0, 14.0); @@ -119,62 +147,92 @@ fn render_demo(context: &mut CanvasRenderingContext2D, // Draw login form. draw_label(context, "Login", RectF::new(position, vec2f(280.0, 20.0))); position += vec2f(0.0, 25.0); - draw_text_edit_box(context, - "E-mail address", - RectF::new(position, vec2f(280.0, 28.0)), - hidpi_factor); + draw_text_edit_box( + context, + "E-mail address", + RectF::new(position, vec2f(280.0, 28.0)), + hidpi_factor, + ); position += vec2f(0.0, 35.0); - draw_text_edit_box(context, - "Password", - RectF::new(position, vec2f(280.0, 28.0)), - hidpi_factor); + draw_text_edit_box( + context, + "Password", + RectF::new(position, vec2f(280.0, 28.0)), + hidpi_factor, + ); position += vec2f(0.0, 38.0); - draw_check_box(context, "Remember me", RectF::new(position, vec2f(140.0, 28.0)), hidpi_factor); - draw_button(context, - Some("🚪"), - "Sign In", - RectF::new(position + vec2f(138.0, 0.0), vec2f(140.0, 28.0)), - rgbu(0, 96, 128)); + draw_check_box( + context, + "Remember me", + RectF::new(position, vec2f(140.0, 28.0)), + hidpi_factor, + ); + draw_button( + context, + Some("🚪"), + "Sign In", + RectF::new(position + vec2f(138.0, 0.0), vec2f(140.0, 28.0)), + rgbu(0, 96, 128), + ); position += vec2f(0.0, 45.0); // Draw slider form. - draw_label(context, "Diameter", RectF::new(position, vec2f(280.0, 20.0))); + draw_label( + context, + "Diameter", + RectF::new(position, vec2f(280.0, 20.0)), + ); position += vec2f(0.0, 25.0); - draw_numeric_edit_box(context, - "123.00", - "px", - RectF::new(position + vec2f(180.0, 0.0), vec2f(100.0, 28.0)), - hidpi_factor); - draw_slider(context, 0.4, RectF::new(position, vec2f(170.0, 28.0)), hidpi_factor); + draw_numeric_edit_box( + context, + "123.00", + "px", + RectF::new(position + vec2f(180.0, 0.0), vec2f(100.0, 28.0)), + hidpi_factor, + ); + draw_slider( + context, + 0.4, + RectF::new(position, vec2f(170.0, 28.0)), + hidpi_factor, + ); position += vec2f(0.0, 55.0); // Draw dialog box buttons. - draw_button(context, - Some("️❌"), - "Delete", - RectF::new(position, vec2f(160.0, 28.0)), - rgbu(128, 16, 8)); - draw_button(context, - None, - "Cancel", - RectF::new(position + vec2f(170.0, 0.0), vec2f(110.0, 28.0)), - rgbau(0, 0, 0, 0)); + draw_button( + context, + Some("️❌"), + "Delete", + RectF::new(position, vec2f(160.0, 28.0)), + rgbu(128, 16, 8), + ); + draw_button( + context, + None, + "Cancel", + RectF::new(position + vec2f(170.0, 0.0), vec2f(110.0, 28.0)), + rgbau(0, 0, 0, 0), + ); // Draw thumbnails. - draw_thumbnails(context, - RectF::new(vec2f(365.0, popup_position.y() - 30.0), vec2f(160.0, 300.0)), - time, - hidpi_factor, - 12, - &data.image); + draw_thumbnails( + context, + RectF::new(vec2f(365.0, popup_position.y() - 30.0), vec2f(160.0, 300.0)), + time, + hidpi_factor, + 12, + &data.image, + ); context.restore(); } -fn draw_eyes(context: &mut CanvasRenderingContext2D, - rect: RectF, - mouse_position: Vector2F, - time: f32) { +fn draw_eyes( + context: &mut CanvasRenderingContext2D, + rect: RectF, + mouse_position: Vector2F, + time: f32, +) { let eyes_radii = rect.size() * vec2f(0.23, 0.5); let eyes_left_position = rect.origin() + eyes_radii; let eyes_right_position = rect.origin() + vec2f(rect.width() - eyes_radii.x(), eyes_radii.y()); @@ -182,19 +240,37 @@ fn draw_eyes(context: &mut CanvasRenderingContext2D, let blink = 1.0 - f32::powf((time * 0.5).sin(), 200.0) * 0.8; let mut gradient = Gradient::linear( - LineSegment2F::new(vec2f(0.0, rect.height() * 0.5), - rect.size() * vec2f(0.1, 1.0)) + rect.origin()); + LineSegment2F::new( + vec2f(0.0, rect.height() * 0.5), + rect.size() * vec2f(0.1, 1.0), + ) + rect.origin(), + ); gradient.add_color_stop(rgbau(0, 0, 0, 32), 0.0); gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0); let mut path = Path2D::new(); - path.ellipse(eyes_left_position + vec2f(3.0, 16.0), eyes_radii, 0.0, 0.0, PI_2); - path.ellipse(eyes_right_position + vec2f(3.0, 16.0), eyes_radii, 0.0, 0.0, PI_2); + path.ellipse( + eyes_left_position + vec2f(3.0, 16.0), + eyes_radii, + 0.0, + 0.0, + PI_2, + ); + path.ellipse( + eyes_right_position + vec2f(3.0, 16.0), + eyes_radii, + 0.0, + 0.0, + PI_2, + ); context.set_fill_style(gradient); context.fill_path(path, FillRule::Winding); - let mut gradient = - Gradient::linear(LineSegment2F::new(vec2f(0.0, rect.height() * 0.25), - rect.size() * vec2f(0.1, 1.0)) + rect.origin()); + let mut gradient = Gradient::linear( + LineSegment2F::new( + vec2f(0.0, rect.height() * 0.25), + rect.size() * vec2f(0.1, 1.0), + ) + rect.origin(), + ); gradient.add_color_stop(rgbu(220, 220, 220), 0.0); gradient.add_color_stop(rgbu(128, 128, 128), 1.0); let mut path = Path2D::new(); @@ -210,16 +286,20 @@ fn draw_eyes(context: &mut CanvasRenderingContext2D, } delta *= eyes_radii * vec2f(0.4, 0.5); let mut path = Path2D::new(); - path.ellipse(eyes_left_position + delta + vec2f(0.0, eyes_radii.y() * 0.25 * (1.0 - blink)), - vec2f(eyes_center, eyes_center * blink), - 0.0, - 0.0, - PI_2); - path.ellipse(eyes_right_position + delta + vec2f(0.0, eyes_radii.y() * 0.25 * (1.0 - blink)), - vec2f(eyes_center, eyes_center * blink), - 0.0, - 0.0, - PI_2); + path.ellipse( + eyes_left_position + delta + vec2f(0.0, eyes_radii.y() * 0.25 * (1.0 - blink)), + vec2f(eyes_center, eyes_center * blink), + 0.0, + 0.0, + PI_2, + ); + path.ellipse( + eyes_right_position + delta + vec2f(0.0, eyes_radii.y() * 0.25 * (1.0 - blink)), + vec2f(eyes_center, eyes_center * blink), + 0.0, + 0.0, + PI_2, + ); context.set_fill_style(rgbu(32, 32, 32)); context.fill_path(path, FillRule::Winding); @@ -243,10 +323,12 @@ fn draw_eyes(context: &mut CanvasRenderingContext2D, context.fill_path(path, FillRule::Winding); } -fn draw_paragraph(context: &mut CanvasRenderingContext2D, - origin: Vector2F, - line_width: f32, - mouse_position: Vector2F) { +fn draw_paragraph( + context: &mut CanvasRenderingContext2D, + origin: Vector2F, + line_width: f32, + mouse_position: Vector2F, +) { const MAIN_LINE_HEIGHT: f32 = 24.0; context.save(); @@ -256,16 +338,19 @@ fn draw_paragraph(context: &mut CanvasRenderingContext2D, context.set_fill_style(ColorU::white()); context.set_text_align(TextAlign::Left); context.set_text_baseline(TextBaseline::Alphabetic); - let main_text = MultilineTextBox::new(context, - PARAGRAPH_TEXT, - origin + vec2f(0.0, 24.0), - line_width); + let main_text = MultilineTextBox::new( + context, + PARAGRAPH_TEXT, + origin + vec2f(0.0, 24.0), + line_width, + ); let main_text_hit_location = main_text.hit_test(context, mouse_position); for (main_text_line_index, main_text_line) in main_text.lines.iter().enumerate() { let bg_alpha = match main_text_hit_location { - Some(ref main_text_hit_location) if - main_text_hit_location.line_index == main_text_line_index as u32 => { + Some(ref main_text_hit_location) + if main_text_hit_location.line_index == main_text_line_index as u32 => + { 64 } _ => 16, @@ -289,15 +374,19 @@ fn draw_paragraph(context: &mut CanvasRenderingContext2D, let gutter_text = format!("{}", text_location.line_index + 1); let gutter_text_metrics = context.measure_text(&gutter_text); - let gutter_text_bounds = - RectF::from_points(vec2f(gutter_text_metrics.actual_bounding_box_left(), - -gutter_text_metrics.font_bounding_box_ascent()), - vec2f(gutter_text_metrics.actual_bounding_box_right(), - -gutter_text_metrics.font_bounding_box_descent())); + let gutter_text_bounds = RectF::from_points( + vec2f( + gutter_text_metrics.actual_bounding_box_left(), + -gutter_text_metrics.font_bounding_box_ascent(), + ), + vec2f( + gutter_text_metrics.actual_bounding_box_right(), + -gutter_text_metrics.font_bounding_box_descent(), + ), + ); let gutter_path_bounds = gutter_text_bounds.dilate(vec2f(4.0, 2.0)); let gutter_path_radius = gutter_path_bounds.width() * 0.5 - 1.0; - let path = create_rounded_rect_path(gutter_path_bounds + gutter_origin, - gutter_path_radius); + let path = create_rounded_rect_path(gutter_path_bounds + gutter_origin, gutter_path_radius); context.fill_path(path, FillRule::Winding); context.set_fill_style(rgbau(32, 32, 32, 255)); @@ -310,16 +399,25 @@ fn draw_paragraph(context: &mut CanvasRenderingContext2D, context.set_text_baseline(TextBaseline::Alphabetic); let tooltip_origin = main_text.bounds.lower_left() + vec2f(0.0, 38.0); let tooltip = MultilineTextBox::new(context, HOVER_TEXT, tooltip_origin, 150.0); - let mouse_vector = mouse_position.clamp(tooltip.bounds.origin(), - tooltip.bounds.lower_right()) - mouse_position; + let mouse_vector = mouse_position.clamp(tooltip.bounds.origin(), tooltip.bounds.lower_right()) + - mouse_position; context.set_global_alpha(util::clamp(mouse_vector.length() / 30.0, 0.0, 1.0)); // Draw tooltip background. context.set_fill_style(rgbau(220, 220, 220, 255)); let mut path = create_rounded_rect_path(tooltip.bounds.dilate(2.0), 3.0); - path.move_to(vec2f(tooltip.bounds.center().x(), tooltip.bounds.origin_y() - 10.0)); - path.line_to(vec2f(tooltip.bounds.center().x() + 7.0, tooltip.bounds.origin_y() + 1.0)); - path.line_to(vec2f(tooltip.bounds.center().x() - 7.0, tooltip.bounds.origin_y() + 1.0)); + path.move_to(vec2f( + tooltip.bounds.center().x(), + tooltip.bounds.origin_y() - 10.0, + )); + path.line_to(vec2f( + tooltip.bounds.center().x() + 7.0, + tooltip.bounds.origin_y() + 1.0, + )); + path.line_to(vec2f( + tooltip.bounds.center().x() - 7.0, + tooltip.bounds.origin_y() + 1.0, + )); context.fill_path(path, FillRule::Winding); // Draw tooltip. @@ -365,21 +463,23 @@ struct LineLocation { } impl MultilineTextBox { - fn new(context: &mut CanvasRenderingContext2D, - text: &str, - mut origin: Vector2F, - max_width: f32) - -> MultilineTextBox { + fn new( + context: &mut CanvasRenderingContext2D, + text: &str, + mut origin: Vector2F, + max_width: f32, + ) -> MultilineTextBox { const LINE_SPACING: f32 = 3.0; let a_b_measure = context.measure_text("A B"); let space_width = a_b_measure.width() - context.measure_text("AB").width(); - let line_height = a_b_measure.em_height_ascent() - a_b_measure.em_height_descent() + - LINE_SPACING; + let line_height = + a_b_measure.em_height_ascent() - a_b_measure.em_height_descent() + LINE_SPACING; - let mut text: VecDeque> = text.split('\n').map(|paragraph| { - paragraph.split(' ').map(|word| word.to_owned()).collect() - }).collect(); + let mut text: VecDeque> = text + .split('\n') + .map(|paragraph| paragraph.split(' ').map(|word| word.to_owned()).collect()) + .collect(); let mut lines = vec![]; let mut bounds = None; @@ -398,7 +498,10 @@ impl MultilineTextBox { } } - MultilineTextBox { bounds: bounds.unwrap_or_default(), lines } + MultilineTextBox { + bounds: bounds.unwrap_or_default(), + lines, + } } fn draw(&self, context: &mut CanvasRenderingContext2D, bg_color: ColorU, fg_color: ColorU) { @@ -407,35 +510,56 @@ impl MultilineTextBox { } } - fn hit_test(&self, context: &CanvasRenderingContext2D, mouse_position: Vector2F) - -> Option { + fn hit_test( + &self, + context: &CanvasRenderingContext2D, + mouse_position: Vector2F, + ) -> Option { for (line_index, line) in self.lines.iter().enumerate() { if line.bounds().contains_point(mouse_position) { if let Some(line_location) = line.hit_test(context, mouse_position) { - return Some(TextLocation { line_index: line_index as u32, line_location }); + return Some(TextLocation { + line_index: line_index as u32, + line_location, + }); } } } None } - fn char_position(&self, context: &CanvasRenderingContext2D, text_location: TextLocation) - -> Vector2F { + fn char_position( + &self, + context: &CanvasRenderingContext2D, + text_location: TextLocation, + ) -> Vector2F { let line = &self.lines[text_location.line_index as usize]; - line.bounds().origin() + vec2f(line.char_position(context, text_location.line_location), - 0.0) + line.bounds().origin() + + vec2f( + line.char_position(context, text_location.line_location), + 0.0, + ) } } impl Line { fn new(origin: Vector2F, max_width: f32) -> Line { - Line { words: vec![], origin, ascent: 0.0, descent: 0.0, width: 0.0, max_width } + Line { + words: vec![], + origin, + ascent: 0.0, + descent: 0.0, + width: 0.0, + max_width, + } } - fn layout(&mut self, - context: &mut CanvasRenderingContext2D, - text: &mut VecDeque, - space_width: f32) { + fn layout( + &mut self, + context: &mut CanvasRenderingContext2D, + text: &mut VecDeque, + space_width: f32, + ) { while let Some(word) = text.pop_front() { let mut word_origin_x = self.width; if self.width > 0.0 { @@ -451,7 +575,11 @@ impl Line { self.ascent = self.ascent.max(word_metrics.em_height_ascent()); self.descent = self.descent.min(word_metrics.em_height_descent()); - self.words.push(Word { metrics: word_metrics, string: word, origin_x: word_origin_x }); + self.words.push(Word { + metrics: word_metrics, + string: word, + origin_x: word_origin_x, + }); self.width = new_line_width; } } @@ -472,12 +600,17 @@ impl Line { } fn bounds(&self) -> RectF { - RectF::new(self.origin - vec2f(0.0, self.ascent), - vec2f(self.width, self.ascent - self.descent)) + RectF::new( + self.origin - vec2f(0.0, self.ascent), + vec2f(self.width, self.ascent - self.descent), + ) } - fn hit_test(&self, context: &CanvasRenderingContext2D, mut mouse_position: Vector2F) - -> Option { + fn hit_test( + &self, + context: &CanvasRenderingContext2D, + mut mouse_position: Vector2F, + ) -> Option { let bounds = self.bounds(); mouse_position -= bounds.origin(); if mouse_position.y() < 0.0 || mouse_position.y() > bounds.height() { @@ -497,8 +630,11 @@ impl Line { None } - fn char_position(&self, context: &CanvasRenderingContext2D, line_location: LineLocation) - -> f32 { + fn char_position( + &self, + context: &CanvasRenderingContext2D, + line_location: LineLocation, + ) -> f32 { let word = &self.words[line_location.word_index as usize]; word.origin_x + word.char_position(context, line_location.char_index) } @@ -507,13 +643,15 @@ impl Line { impl Word { fn hit_test(&self, context: &CanvasRenderingContext2D, position_x: f32) -> u32 { let (mut char_start_x, mut prev_char_index) = (self.origin_x, 0); - for char_index in self.string - .char_indices() - .map(|(index, _)| index) - .skip(1) - .chain(iter::once(self.string.len())) { - let char_end_x = self.origin_x + - context.measure_text(&self.string[0..char_index]).width(); + for char_index in self + .string + .char_indices() + .map(|(index, _)| index) + .skip(1) + .chain(iter::once(self.string.len())) + { + let char_end_x = + self.origin_x + context.measure_text(&self.string[0..char_index]).width(); if position_x <= (char_start_x + char_end_x) * 0.5 { return prev_char_index; } @@ -524,7 +662,9 @@ impl Word { } fn char_position(&self, context: &CanvasRenderingContext2D, char_index: u32) -> f32 { - context.measure_text(&self.string[0..(char_index as usize)]).width() + context + .measure_text(&self.string[0..(char_index as usize)]) + .width() } } @@ -532,25 +672,26 @@ fn draw_graph(context: &mut CanvasRenderingContext2D, rect: RectF, time: f32) { let sample_spread = rect.width() / 5.0; let samples = [ - (1.0 + f32::sin(time * 1.2345 + f32::cos(time * 0.33457) * 0.44)) * 0.5, - (1.0 + f32::sin(time * 0.68363 + f32::cos(time * 1.30) * 1.55)) * 0.5, - (1.0 + f32::sin(time * 1.1642 + f32::cos(time * 0.33457) * 1.24)) * 0.5, - (1.0 + f32::sin(time * 0.56345 + f32::cos(time * 1.63) * 0.14)) * 0.5, - (1.0 + f32::sin(time * 1.6245 + f32::cos(time * 0.254) * 0.3)) * 0.5, - (1.0 + f32::sin(time * 0.345 + f32::cos(time * 0.03) * 0.6)) * 0.5, + (1.0 + f32::sin(time * 1.2345 + f32::cos(time * 0.33457) * 0.44)) * 0.5, + (1.0 + f32::sin(time * 0.68363 + f32::cos(time * 1.30) * 1.55)) * 0.5, + (1.0 + f32::sin(time * 1.1642 + f32::cos(time * 0.33457) * 1.24)) * 0.5, + (1.0 + f32::sin(time * 0.56345 + f32::cos(time * 1.63) * 0.14)) * 0.5, + (1.0 + f32::sin(time * 1.6245 + f32::cos(time * 0.254) * 0.3)) * 0.5, + (1.0 + f32::sin(time * 0.345 + f32::cos(time * 0.03) * 0.6)) * 0.5, ]; let sample_scale = vec2f(sample_spread, rect.height() * 0.8); - let sample_points: ArrayVec<[Vector2F; 6]> = samples.iter() - .enumerate() - .map(|(index, &sample)| { - rect.origin() + vec2f(index as f32, sample) * sample_scale - }).collect(); + let sample_points: ArrayVec<[Vector2F; 6]> = samples + .iter() + .enumerate() + .map(|(index, &sample)| rect.origin() + vec2f(index as f32, sample) * sample_scale) + .collect(); // Draw graph background. let mut background = Gradient::linear( - LineSegment2F::new(vec2f(0.0, 0.0), vec2f(0.0, rect.height())) + rect.origin()); - background.add_color_stop(rgbau(0, 160, 192, 0), 0.0); + LineSegment2F::new(vec2f(0.0, 0.0), vec2f(0.0, rect.height())) + rect.origin(), + ); + background.add_color_stop(rgbau(0, 160, 192, 0), 0.0); background.add_color_stop(rgbau(0, 160, 192, 64), 1.0); context.set_fill_style(background); let mut path = create_graph_path(&sample_points, sample_spread, Vector2F::zero()); @@ -575,9 +716,12 @@ fn draw_graph(context: &mut CanvasRenderingContext2D, rect: RectF, time: f32) { let gradient_center = sample_point + vec2f(0.0, 2.0); let mut background = Gradient::radial(gradient_center, F32x2::new(3.0, 8.0)); background.add_color_stop(rgbau(0, 0, 0, 32), 0.0); - background.add_color_stop(rgbau(0, 0, 0, 0), 1.0); + background.add_color_stop(rgbau(0, 0, 0, 0), 1.0); context.set_fill_style(background); - context.fill_rect(RectF::new(sample_point + vec2f(-10.0, -10.0 + 2.0), vec2f(20.0, 20.0))); + context.fill_rect(RectF::new( + sample_point + vec2f(-10.0, -10.0 + 2.0), + vec2f(20.0, 20.0), + )); } // Draw sample positions. @@ -598,10 +742,12 @@ fn draw_graph(context: &mut CanvasRenderingContext2D, rect: RectF, time: f32) { context.set_line_width(1.0); } -fn draw_color_wheel(context: &mut CanvasRenderingContext2D, - rect: RectF, - time: f32, - hidpi_factor: f32) { +fn draw_color_wheel( + context: &mut CanvasRenderingContext2D, + rect: RectF, + time: f32, + hidpi_factor: f32, +) { let hue = (time * 0.12).sin() * PI_2; context.save(); @@ -615,20 +761,34 @@ fn draw_color_wheel(context: &mut CanvasRenderingContext2D, // Draw outer circle. for segment in 0..6 { - let start_angle = segment as f32 / 6.0 * PI_2 - half_arc_len; - let end_angle = (segment + 1) as f32 / 6.0 * PI_2 + half_arc_len; - let line = LineSegment2F::new(vec2f(f32::cos(start_angle), f32::sin(start_angle)), - vec2f(f32::cos(end_angle), f32::sin(end_angle))); + let start_angle = segment as f32 / 6.0 * PI_2 - half_arc_len; + let end_angle = (segment + 1) as f32 / 6.0 * PI_2 + half_arc_len; + let line = LineSegment2F::new( + vec2f(f32::cos(start_angle), f32::sin(start_angle)), + vec2f(f32::cos(end_angle), f32::sin(end_angle)), + ); let scale = util::lerp(inner_radius, outer_radius, 0.5); let mut gradient = Gradient::linear(line * scale + center); let start_color = ColorF::from_hsl(start_angle, 1.0, 0.55).to_u8(); - let end_color = ColorF::from_hsl(end_angle, 1.0, 0.55).to_u8(); + let end_color = ColorF::from_hsl(end_angle, 1.0, 0.55).to_u8(); gradient.add_color_stop(start_color, 0.0); - gradient.add_color_stop(end_color, 1.0); + gradient.add_color_stop(end_color, 1.0); context.set_fill_style(gradient); let mut path = Path2D::new(); - path.arc(center, inner_radius, start_angle, end_angle, ArcDirection::CW); - path.arc(center, outer_radius, end_angle, start_angle, ArcDirection::CCW); + path.arc( + center, + inner_radius, + start_angle, + end_angle, + ArcDirection::CW, + ); + path.arc( + center, + outer_radius, + end_angle, + start_angle, + ArcDirection::CCW, + ); path.close_path(); context.fill_path(path, FillRule::Winding); } @@ -652,8 +812,10 @@ fn draw_color_wheel(context: &mut CanvasRenderingContext2D, context.set_shadow_offset(vec2f(0.0, 0.0)); context.set_stroke_style(rgbau(255, 255, 255, 192)); context.set_line_width(2.0); - context.stroke_rect(RectF::new(vec2f(inner_radius - 1.0, -3.0), - vec2f(outer_radius - inner_radius + 2.0, 6.0))); + context.stroke_rect(RectF::new( + vec2f(inner_radius - 1.0, -3.0), + vec2f(outer_radius - inner_radius + 2.0, 6.0), + )); context.set_shadow_color(ColorU::transparent_black()); // Draw center triangle. @@ -664,11 +826,12 @@ fn draw_color_wheel(context: &mut CanvasRenderingContext2D, let mut gradient_0 = Gradient::linear_from_points(triangle_vertex_a, triangle_vertex_b); gradient_0.add_color_stop(ColorF::from_hsl(hue, 1.0, 0.5).to_u8(), 0.0); gradient_0.add_color_stop(ColorU::white(), 1.0); - let mut gradient_1 = - Gradient::linear_from_points(triangle_vertex_a.lerp(triangle_vertex_b, 0.5), - triangle_vertex_c); + let mut gradient_1 = Gradient::linear_from_points( + triangle_vertex_a.lerp(triangle_vertex_b, 0.5), + triangle_vertex_c, + ); gradient_1.add_color_stop(ColorU::transparent_black(), 0.0); - gradient_1.add_color_stop(ColorU::black(), 1.0); + gradient_1.add_color_stop(ColorU::black(), 1.0); let mut path = Path2D::new(); path.move_to(triangle_vertex_a); path.line_to(triangle_vertex_b); @@ -682,8 +845,8 @@ fn draw_color_wheel(context: &mut CanvasRenderingContext2D, context.stroke_path(path); // Stroke the selection circle on the triangle. - let selection_circle_center = vec2f(FRAC_PI_2_3.cos(), FRAC_PI_2_3.sin()) * triangle_radius * - vec2f(0.3, 0.4); + let selection_circle_center = + vec2f(FRAC_PI_2_3.cos(), FRAC_PI_2_3.sin()) * triangle_radius * vec2f(0.3, 0.4); context.set_stroke_style(rgbau(255, 255, 255, 192)); context.set_line_width(2.0); let mut path = Path2D::new(); @@ -693,10 +856,13 @@ fn draw_color_wheel(context: &mut CanvasRenderingContext2D, // Fill the selection circle. let mut gradient = Gradient::radial(selection_circle_center, F32x2::new(7.0, 9.0)); gradient.add_color_stop(rgbau(0, 0, 0, 64), 0.0); - gradient.add_color_stop(rgbau(0, 0, 0, 0), 1.0); + gradient.add_color_stop(rgbau(0, 0, 0, 0), 1.0); context.set_fill_style(gradient); let mut path = Path2D::new(); - path.rect(RectF::new(selection_circle_center - vec2f(20.0, 20.0), vec2f(40.0, 40.0))); + path.rect(RectF::new( + selection_circle_center - vec2f(20.0, 20.0), + vec2f(40.0, 40.0), + )); path.ellipse(selection_circle_center, vec2f(7.0, 7.0), 0.0, 0.0, PI_2); context.fill_path(path, FillRule::EvenOdd); @@ -712,22 +878,33 @@ fn draw_lines(context: &mut CanvasRenderingContext2D, rect: RectF, time: f32) { context.save(); let points = [ - vec2f(-spacing * 0.25 + f32::cos(time * 0.3) * spacing * 0.5, - f32::sin(time * 0.3) * spacing * 0.5), + vec2f( + -spacing * 0.25 + f32::cos(time * 0.3) * spacing * 0.5, + f32::sin(time * 0.3) * spacing * 0.5, + ), vec2f(-spacing * 0.25, 0.0), - vec2f( spacing * 0.25, 0.0), - vec2f( spacing * 0.25 + f32::cos(time * -0.3) * spacing * 0.5, - f32::sin(time * -0.3) * spacing * 0.5), + vec2f(spacing * 0.25, 0.0), + vec2f( + spacing * 0.25 + f32::cos(time * -0.3) * spacing * 0.5, + f32::sin(time * -0.3) * spacing * 0.5, + ), ]; - for (cap_index, &cap) in [LineCap::Butt, LineCap::Round, LineCap::Square].iter().enumerate() { - for (join_index, &join) in [ - LineJoin::Miter, LineJoin::Round, LineJoin::Bevel - ].iter().enumerate() { - let origin = rect.origin() + - vec2f(0.5, -0.5) * spacing + - vec2f((cap_index * 3 + join_index) as f32 / 9.0 * rect.width(), 0.0) + - PADDING; + for (cap_index, &cap) in [LineCap::Butt, LineCap::Round, LineCap::Square] + .iter() + .enumerate() + { + for (join_index, &join) in [LineJoin::Miter, LineJoin::Round, LineJoin::Bevel] + .iter() + .enumerate() + { + let origin = rect.origin() + + vec2f(0.5, -0.5) * spacing + + vec2f( + (cap_index * 3 + join_index) as f32 / 9.0 * rect.width(), + 0.0, + ) + + PADDING; context.set_line_cap(cap); context.set_line_join(join); @@ -779,12 +956,15 @@ fn draw_caps(context: &mut CanvasRenderingContext2D, rect: RectF) { context.fill_rect(rect); context.set_line_width(LINE_WIDTH); - for (cap_index, &cap) in [LineCap::Butt, LineCap::Round, LineCap::Square].iter().enumerate() { + for (cap_index, &cap) in [LineCap::Butt, LineCap::Round, LineCap::Square] + .iter() + .enumerate() + { context.set_line_cap(cap); context.set_stroke_style(ColorU::black()); let offset = cap_index as f32 * 10.0 + 5.0; let mut path = Path2D::new(); - path.move_to(rect.origin() + vec2f(0.0, offset)); + path.move_to(rect.origin() + vec2f(0.0, offset)); path.line_to(rect.upper_right() + vec2f(0.0, offset)); context.stroke_path(path); } @@ -797,8 +977,8 @@ fn draw_clip(context: &mut CanvasRenderingContext2D, origin: Vector2F, time: f32 // Draw first rect. let original_transform = context.transform(); - let transform_a = original_transform * - Transform2F::from_rotation(angle::angle_from_degrees(5.0)).translate(origin); + let transform_a = original_transform + * Transform2F::from_rotation(angle::angle_from_degrees(5.0)).translate(origin); context.set_transform(&transform_a); context.set_fill_style(rgbu(255, 0, 0)); let mut clip_path_a = Path2D::new(); @@ -815,8 +995,9 @@ fn draw_clip(context: &mut CanvasRenderingContext2D, origin: Vector2F, time: f32 // Draw second rectangle with clip. let mut clip_path_b = Path2D::new(); - let clip_rect_b = (transform_b.inverse() * transform_a * clip_rect_a).intersection(fill_rect) - .unwrap_or_default(); + let clip_rect_b = (transform_b.inverse() * transform_a * clip_rect_a) + .intersection(fill_rect) + .unwrap_or_default(); clip_path_b.rect(clip_rect_b); context.clip_path(clip_path_b, FillRule::Winding); context.set_fill_style(rgbu(255, 128, 0)); @@ -825,10 +1006,12 @@ fn draw_clip(context: &mut CanvasRenderingContext2D, origin: Vector2F, time: f32 context.restore(); } -fn draw_window(context: &mut CanvasRenderingContext2D, - title: &str, - rect: RectF, - hidpi_factor: f32) { +fn draw_window( + context: &mut CanvasRenderingContext2D, + title: &str, + rect: RectF, + hidpi_factor: f32, +) { const CORNER_RADIUS: f32 = 3.0; context.save(); @@ -838,19 +1021,28 @@ fn draw_window(context: &mut CanvasRenderingContext2D, context.set_shadow_blur(10.0 * hidpi_factor); context.set_shadow_offset(vec2f(0.0, 2.0)); context.set_shadow_color(rgbau(0, 0, 0, 128)); - context.fill_path(create_rounded_rect_path(rect, CORNER_RADIUS), FillRule::Winding); + context.fill_path( + create_rounded_rect_path(rect, CORNER_RADIUS), + FillRule::Winding, + ); context.set_shadow_color(rgbau(0, 0, 0, 0)); // Header. let mut header_gradient = Gradient::linear(LineSegment2F::new(Vector2F::zero(), vec2f(0.0, 15.0)) + rect.origin()); - header_gradient.add_color_stop(rgbau(255, 255, 255, 8), 0.0); - header_gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0); + header_gradient.add_color_stop(rgbau(255, 255, 255, 8), 0.0); + header_gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0); context.set_fill_style(header_gradient); - context.fill_path(create_rounded_rect_path(RectF::new(rect.origin() + vec2f(1.0, 1.0), - vec2f(rect.width() - 2.0, 30.0)), - CORNER_RADIUS - 1.0), - FillRule::Winding); + context.fill_path( + create_rounded_rect_path( + RectF::new( + rect.origin() + vec2f(1.0, 1.0), + vec2f(rect.width() - 2.0, 30.0), + ), + CORNER_RADIUS - 1.0, + ), + FillRule::Winding, + ); let mut path = Path2D::new(); path.move_to(rect.origin() + vec2f(0.5, 30.5)); path.line_to(rect.origin() + vec2f(rect.width() - 0.5, 30.5)); @@ -870,10 +1062,12 @@ fn draw_window(context: &mut CanvasRenderingContext2D, context.restore(); } -fn draw_search_box(context: &mut CanvasRenderingContext2D, - text: &str, - rect: RectF, - hidpi_factor: f32) { +fn draw_search_box( + context: &mut CanvasRenderingContext2D, + text: &str, + rect: RectF, + hidpi_factor: f32, +) { let corner_radius = rect.height() * 0.5 - 1.0; let path = create_rounded_rect_path(rect, corner_radius); @@ -907,7 +1101,10 @@ fn draw_search_box(context: &mut CanvasRenderingContext2D, context.set_font_size(rect.height() * 0.5); context.set_font(FONT_NAME_EMOJI); context.set_text_align(TextAlign::Center); - context.fill_text("️❌", rect.upper_right() + vec2f(-1.0, 1.0) * (rect.height() * 0.55)); + context.fill_text( + "️❌", + rect.upper_right() + vec2f(-1.0, 1.0) * (rect.height() * 0.55), + ); } fn draw_dropdown(context: &mut CanvasRenderingContext2D, text: &str, rect: RectF) { @@ -915,13 +1112,18 @@ fn draw_dropdown(context: &mut CanvasRenderingContext2D, text: &str, rect: RectF let mut background_gradient = Gradient::linear_from_points(rect.origin(), rect.lower_left()); background_gradient.add_color_stop(rgbau(255, 255, 255, 16), 0.0); - background_gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0); + background_gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0); context.set_fill_style(background_gradient); - context.fill_path(create_rounded_rect_path(rect.contract(1.0), CORNER_RADIUS - 1.0), - FillRule::Winding); + context.fill_path( + create_rounded_rect_path(rect.contract(1.0), CORNER_RADIUS - 1.0), + FillRule::Winding, + ); context.set_stroke_style(rgbau(0, 0, 0, 48)); - context.stroke_path(create_rounded_rect_path(rect.contract(0.5), CORNER_RADIUS - 0.5)); + context.stroke_path(create_rounded_rect_path( + rect.contract(0.5), + CORNER_RADIUS - 0.5, + )); context.set_font(FONT_NAME_REGULAR); context.set_font_size(17.0); @@ -937,9 +1139,9 @@ fn draw_dropdown(context: &mut CanvasRenderingContext2D, text: &str, rect: RectF context.scale(0.1); context.set_fill_style(rgbau(255, 255, 255, 64)); let mut path = Path2D::new(); - path.move_to(vec2f(0.0, 100.0)); + path.move_to(vec2f(0.0, 100.0)); path.line_to(vec2f(32.8, 50.0)); - path.line_to(vec2f(0.0, 0.0)); + path.line_to(vec2f(0.0, 0.0)); path.line_to(vec2f(22.1, 0.0)); path.line_to(vec2f(54.2, 50.0)); path.line_to(vec2f(22.1, 100.0)); @@ -974,13 +1176,18 @@ fn draw_edit_box(context: &mut CanvasRenderingContext2D, rect: RectF, hidpi_fact context.restore(); context.set_stroke_style(rgbau(0, 0, 0, 48)); - context.stroke_path(create_rounded_rect_path(rect.contract(0.5), CORNER_RADIUS - 0.5)); + context.stroke_path(create_rounded_rect_path( + rect.contract(0.5), + CORNER_RADIUS - 0.5, + )); } -fn draw_text_edit_box(context: &mut CanvasRenderingContext2D, - text: &str, - rect: RectF, - hidpi_factor: f32) { +fn draw_text_edit_box( + context: &mut CanvasRenderingContext2D, + text: &str, + rect: RectF, + hidpi_factor: f32, +) { draw_edit_box(context, rect, hidpi_factor); context.set_font(FONT_NAME_REGULAR); @@ -991,11 +1198,13 @@ fn draw_text_edit_box(context: &mut CanvasRenderingContext2D, context.fill_text(text, rect.origin() + vec2f(0.3, 0.5) * rect.height()); } -fn draw_numeric_edit_box(context: &mut CanvasRenderingContext2D, - value: &str, - unit: &str, - rect: RectF, - hidpi_factor: f32) { +fn draw_numeric_edit_box( + context: &mut CanvasRenderingContext2D, + value: &str, + unit: &str, + rect: RectF, + hidpi_factor: f32, +) { draw_edit_box(context, rect, hidpi_factor); context.set_font(FONT_NAME_REGULAR); @@ -1011,14 +1220,18 @@ fn draw_numeric_edit_box(context: &mut CanvasRenderingContext2D, context.set_fill_style(rgbau(255, 255, 255, 128)); context.set_text_align(TextAlign::Right); context.set_text_baseline(TextBaseline::Middle); - context.fill_text(value, rect.upper_right() + vec2f(-unit_width - rect.height() * 0.5, - rect.height() * 0.5)); + context.fill_text( + value, + rect.upper_right() + vec2f(-unit_width - rect.height() * 0.5, rect.height() * 0.5), + ); } -fn draw_check_box(context: &mut CanvasRenderingContext2D, - text: &str, - rect: RectF, - hidpi_factor: f32) { +fn draw_check_box( + context: &mut CanvasRenderingContext2D, + text: &str, + rect: RectF, + hidpi_factor: f32, +) { const CORNER_RADIUS: f32 = 3.0; context.set_font(FONT_NAME_REGULAR); @@ -1029,8 +1242,11 @@ fn draw_check_box(context: &mut CanvasRenderingContext2D, context.fill_text(text, rect.origin() + vec2f(28.0, rect.height() * 0.5)); context.save(); - let check_box_rect = RectF::new(vec2f(rect.origin_x(), rect.center().y().floor() - 9.0), - vec2f(20.0, 20.0)).contract(1.0); + let check_box_rect = RectF::new( + vec2f(rect.origin_x(), rect.center().y().floor() - 9.0), + vec2f(20.0, 20.0), + ) + .contract(1.0); let check_box_path = create_rounded_rect_path(check_box_rect, CORNER_RADIUS); context.set_fill_style(rgbau(0, 0, 0, 32)); context.fill_path(check_box_path.clone(), FillRule::Winding); @@ -1051,11 +1267,13 @@ fn draw_check_box(context: &mut CanvasRenderingContext2D, context.fill_text("✔︎", check_box_rect.center()); } -fn draw_button(context: &mut CanvasRenderingContext2D, - pre_icon: Option<&str>, - text: &str, - rect: RectF, - color: ColorU) { +fn draw_button( + context: &mut CanvasRenderingContext2D, + pre_icon: Option<&str>, + text: &str, + rect: RectF, + color: ColorU, +) { const CORNER_RADIUS: f32 = 4.0; let path = create_rounded_rect_path(rect.contract(1.0), CORNER_RADIUS - 1.0); @@ -1063,15 +1281,22 @@ fn draw_button(context: &mut CanvasRenderingContext2D, context.set_fill_style(color); context.fill_path(path.clone(), FillRule::Winding); } - let alpha = if color == ColorU::transparent_black() { 16 } else { 32 }; + let alpha = if color == ColorU::transparent_black() { + 16 + } else { + 32 + }; let mut background_gradient = Gradient::linear_from_points(rect.origin(), rect.lower_left()); background_gradient.add_color_stop(rgbau(255, 255, 255, alpha), 0.0); - background_gradient.add_color_stop(rgbau(0, 0, 0, alpha), 1.0); + background_gradient.add_color_stop(rgbau(0, 0, 0, alpha), 1.0); context.set_fill_style(background_gradient); context.fill_path(path, FillRule::Winding); context.set_stroke_style(rgbau(0, 0, 0, 48)); - context.stroke_path(create_rounded_rect_path(rect.contract(0.5), CORNER_RADIUS - 0.5)); + context.stroke_path(create_rounded_rect_path( + rect.contract(0.5), + CORNER_RADIUS - 0.5, + )); context.set_font(FONT_NAME_BOLD); context.set_font_size(17.0); @@ -1087,8 +1312,10 @@ fn draw_button(context: &mut CanvasRenderingContext2D, context.set_fill_style(rgbau(255, 255, 255, 96)); context.set_text_align(TextAlign::Left); context.set_text_baseline(TextBaseline::Middle); - context.fill_text(icon, - rect.center() - vec2f(text_width * 0.5 + icon_width * 0.75, 0.0)); + context.fill_text( + icon, + rect.center() - vec2f(text_width * 0.5 + icon_width * 0.75, 0.0), + ); } } @@ -1105,17 +1332,17 @@ fn draw_button(context: &mut CanvasRenderingContext2D, context.set_shadow_color(ColorU::transparent_black()); } -fn draw_slider(context: &mut CanvasRenderingContext2D, - value: f32, - rect: RectF, - hidpi_factor: f32) { +fn draw_slider(context: &mut CanvasRenderingContext2D, value: f32, rect: RectF, hidpi_factor: f32) { let (center_y, knob_radius) = (rect.center().y().floor(), (rect.height() * 0.25).floor()); context.save(); // Draw track. context.save(); - let track_rect = RectF::new(vec2f(rect.origin_x(), center_y - 2.0), vec2f(rect.width(), 4.0)); + let track_rect = RectF::new( + vec2f(rect.origin_x(), center_y - 2.0), + vec2f(rect.width(), 4.0), + ); let track_path = create_rounded_rect_path(track_rect, 2.0); context.clip_path(track_path.clone(), FillRule::Winding); context.set_shadow_blur(2.0 * hidpi_factor); @@ -1127,11 +1354,12 @@ fn draw_slider(context: &mut CanvasRenderingContext2D, // Fill knob. let knob_position = vec2f(rect.origin_x() + (value * rect.width()).floor(), center_y); - let mut background_gradient = - Gradient::linear_from_points(knob_position - vec2f(0.0, knob_radius), - knob_position + vec2f(0.0, knob_radius)); + let mut background_gradient = Gradient::linear_from_points( + knob_position - vec2f(0.0, knob_radius), + knob_position + vec2f(0.0, knob_radius), + ); background_gradient.add_color_stop(rgbau(255, 255, 255, 16), 0.0); - background_gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0); + background_gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0); let mut path = Path2D::new(); path.ellipse(knob_position, knob_radius - 1.0, 0.0, 0.0, PI_2); context.set_fill_style(rgbu(40, 43, 48)); @@ -1152,12 +1380,14 @@ fn draw_slider(context: &mut CanvasRenderingContext2D, context.restore(); } -fn draw_thumbnails(context: &mut CanvasRenderingContext2D, - rect: RectF, - time: f32, - hidpi_factor: f32, - image_count: usize, - image: &Image) { +fn draw_thumbnails( + context: &mut CanvasRenderingContext2D, + rect: RectF, + time: f32, + hidpi_factor: f32, + image_count: usize, + image: &Image, +) { const CORNER_RADIUS: f32 = 3.0; const THUMB_HEIGHT: f32 = 60.0; const ARROW_Y_POSITION: f32 = 30.5; @@ -1192,9 +1422,11 @@ fn draw_thumbnails(context: &mut CanvasRenderingContext2D, context.translate(vec2f(0.0, -scroll_y * (stack_height - rect.height()))); for image_index in 0..image_count { - let image_origin = rect.origin() + vec2f(10.0, 10.0) + - vec2i(image_index as i32 % 2, image_index as i32 / 2).to_f32() * (THUMB_HEIGHT + 10.0); - let image_rect = RectF::new(image_origin, Vector2F::splat(THUMB_HEIGHT)); + let image_origin = rect.origin() + + vec2f(10.0, 10.0) + + vec2i(image_index as i32 % 2, image_index as i32 / 2).to_f32() + * (THUMB_HEIGHT + 10.0); + let image_rect = RectF::new(image_origin, Vector2F::splat(THUMB_HEIGHT)); // Draw shadow. let shadow_path = create_rounded_rect_path(image_rect.dilate(1.0) + vec2f(0.0, 1.0), 5.0); @@ -1212,12 +1444,15 @@ fn draw_thumbnails(context: &mut CanvasRenderingContext2D, } let image_path = create_rounded_rect_path(image_rect, 5.0); - let image_coord = vec2i((image_index % IMAGES_ACROSS) as i32, - (image_index / IMAGES_ACROSS) as i32); - let pattern_transform = Transform2F::from_translation(image_rect.origin()) * - Transform2F::from_scale(0.5) * - Transform2F::from_translation(-image_coord.to_f32() * (THUMB_HEIGHT * 2.0 + 2.0) - - 1.0); + let image_coord = vec2i( + (image_index % IMAGES_ACROSS) as i32, + (image_index / IMAGES_ACROSS) as i32, + ); + let pattern_transform = Transform2F::from_translation(image_rect.origin()) + * Transform2F::from_scale(0.5) + * Transform2F::from_translation( + -image_coord.to_f32() * (THUMB_HEIGHT * 2.0 + 2.0) - 1.0, + ); let mut pattern = Pattern::from_image((*image).clone()); pattern.apply_transform(pattern_transform); context.set_fill_style(pattern); @@ -1233,26 +1468,33 @@ fn draw_thumbnails(context: &mut CanvasRenderingContext2D, // Draw fade-away gradients. - let mut fade_gradient = Gradient::linear_from_points(rect.origin(), - rect.origin() + vec2f(0.0, 6.0)); + let mut fade_gradient = + Gradient::linear_from_points(rect.origin(), rect.origin() + vec2f(0.0, 6.0)); fade_gradient.add_color_stop(rgbau(200, 200, 200, 255), 0.0); - fade_gradient.add_color_stop(rgbau(200, 200, 200, 0), 1.0); + fade_gradient.add_color_stop(rgbau(200, 200, 200, 0), 1.0); context.set_fill_style(fade_gradient); - context.fill_rect(RectF::new(rect.origin() + vec2f(4.0, 0.0), vec2f(rect.width() - 8.0, 6.0))); + context.fill_rect(RectF::new( + rect.origin() + vec2f(4.0, 0.0), + vec2f(rect.width() - 8.0, 6.0), + )); - let mut fade_gradient = Gradient::linear_from_points(rect.lower_left(), - rect.lower_left() - vec2f(0.0, 6.0)); + let mut fade_gradient = + Gradient::linear_from_points(rect.lower_left(), rect.lower_left() - vec2f(0.0, 6.0)); fade_gradient.add_color_stop(rgbau(200, 200, 200, 255), 0.0); - fade_gradient.add_color_stop(rgbau(200, 200, 200, 0), 1.0); + fade_gradient.add_color_stop(rgbau(200, 200, 200, 0), 1.0); context.set_fill_style(fade_gradient); - context.fill_rect(RectF::new(rect.lower_left() + vec2f(4.0, -6.0), - vec2f(rect.width() - 8.0, 6.0))); + context.fill_rect(RectF::new( + rect.lower_left() + vec2f(4.0, -6.0), + vec2f(rect.width() - 8.0, 6.0), + )); // Draw scroll bar. context.save(); - let scroll_bar_rect = RectF::new(rect.upper_right() + vec2f(-12.0, 4.0), - vec2f(8.0, rect.height() - 8.0)); + let scroll_bar_rect = RectF::new( + rect.upper_right() + vec2f(-12.0, 4.0), + vec2f(8.0, rect.height() - 8.0), + ); let path = create_rounded_rect_path(scroll_bar_rect, CORNER_RADIUS); context.set_fill_style(rgbau(0, 0, 0, 32)); context.fill_path(path.clone(), FillRule::Winding); @@ -1268,7 +1510,8 @@ fn draw_thumbnails(context: &mut CanvasRenderingContext2D, let knob_rect = RectF::new( scroll_bar_rect.origin() + vec2f(0.0, (rect.height() - 8.0 - scroll_height) * scroll_y), - vec2f(8.0, scroll_height)); + vec2f(8.0, scroll_height), + ); context.set_fill_style(rgbu(220, 220, 220)); let path = create_rounded_rect_path(knob_rect.contract(1.0), 3.0); context.fill_path(path.clone(), FillRule::Winding); @@ -1292,15 +1535,28 @@ fn draw_spinner(context: &mut CanvasRenderingContext2D, center: Vector2F, radius context.save(); let mut path = Path2D::new(); - path.arc(center, outer_radius, start_angle, end_angle, ArcDirection::CW); - path.arc(center, inner_radius, end_angle, start_angle, ArcDirection::CCW); + path.arc( + center, + outer_radius, + start_angle, + end_angle, + ArcDirection::CW, + ); + path.arc( + center, + inner_radius, + end_angle, + start_angle, + ArcDirection::CCW, + ); path.close_path(); set_linear_gradient_fill_style( context, center + vec2f(outer_radius.cos(), outer_radius.sin()) * average_radius, center + vec2f(inner_radius.cos(), inner_radius.sin()) * average_radius, rgbau(0, 0, 0, 0), - rgbau(0, 0, 0, 128)); + rgbau(0, 0, 0, 128), + ); context.fill_path(path, FillRule::Winding); context.restore(); @@ -1314,7 +1570,11 @@ struct PerfGraph { impl PerfGraph { fn new(style: GraphStyle, name: &'static str) -> PerfGraph { - PerfGraph { style, name, values: VecDeque::new() } + PerfGraph { + style, + name, + values: VecDeque::new(), + } } fn push(&mut self, frame_time: f32) { @@ -1332,7 +1592,10 @@ impl PerfGraph { let mut path = Path2D::new(); path.move_to(rect.lower_left()); - let scale = vec2f(rect.width() / (GRAPH_HISTORY_COUNT as f32 - 1.0), rect.height()); + let scale = vec2f( + rect.width() / (GRAPH_HISTORY_COUNT as f32 - 1.0), + rect.height(), + ); for (index, value) in self.values.iter().enumerate() { let mut value = *value; if self.style == GraphStyle::FPS && value != 0.0 { @@ -1365,14 +1628,20 @@ impl PerfGraph { if self.style == GraphStyle::FPS { context.set_text_baseline(TextBaseline::Alphabetic); context.set_fill_style(rgbau(240, 240, 240, 160)); - self.draw_label(context, GraphStyle::MS, rect.lower_right() + vec2f(-3.0, -3.0)); + self.draw_label( + context, + GraphStyle::MS, + rect.lower_right() + vec2f(-3.0, -3.0), + ); } } - fn draw_label(&self, - context: &mut CanvasRenderingContext2D, - style: GraphStyle, - origin: Vector2F) { + fn draw_label( + &self, + context: &mut CanvasRenderingContext2D, + style: GraphStyle, + origin: Vector2F, + ) { let mut average = self.average(); if style == GraphStyle::FPS && average != 0.0 { average = 1.0 / average; @@ -1419,11 +1688,13 @@ impl GraphStyle { } } -fn set_linear_gradient_fill_style(context: &mut CanvasRenderingContext2D, - from_position: Vector2F, - to_position: Vector2F, - from_color: ColorU, - to_color: ColorU) { +fn set_linear_gradient_fill_style( + context: &mut CanvasRenderingContext2D, + from_position: Vector2F, + to_position: Vector2F, + from_color: ColorU, + to_color: ColorU, +) { let mut gradient = Gradient::linear(LineSegment2F::new(from_position, to_position)); gradient.add_color_stop(from_color, 0.0); gradient.add_color_stop(to_color, 1.0); @@ -1434,9 +1705,11 @@ fn create_graph_path(sample_points: &[Vector2F], sample_spread: f32, offset: Vec let mut path = Path2D::new(); path.move_to(sample_points[0] + vec2f(0.0, 2.0)); for pair in sample_points.windows(2) { - path.bezier_curve_to(pair[0] + offset + vec2f(sample_spread * 0.5, 0.0), - pair[1] + offset - vec2f(sample_spread * 0.5, 0.0), - pair[1] + offset); + path.bezier_curve_to( + pair[0] + offset + vec2f(sample_spread * 0.5, 0.0), + pair[1] + offset - vec2f(sample_spread * 0.5, 0.0), + pair[1] + offset, + ); } path } @@ -1444,10 +1717,22 @@ fn create_graph_path(sample_points: &[Vector2F], sample_spread: f32, offset: Vec fn create_rounded_rect_path(rect: RectF, radius: f32) -> Path2D { let mut path = Path2D::new(); path.move_to(rect.origin() + vec2f(radius, 0.0)); - path.arc_to(rect.upper_right(), rect.upper_right() + vec2f(0.0, radius), radius); - path.arc_to(rect.lower_right(), rect.lower_right() + vec2f(-radius, 0.0), radius); - path.arc_to(rect.lower_left(), rect.lower_left() + vec2f(0.0, -radius), radius); - path.arc_to(rect.origin(), rect.origin() + vec2f(radius, 0.0), radius); + path.arc_to( + rect.upper_right(), + rect.upper_right() + vec2f(0.0, radius), + radius, + ); + path.arc_to( + rect.lower_right(), + rect.lower_right() + vec2f(-radius, 0.0), + radius, + ); + path.arc_to( + rect.lower_left(), + rect.lower_left() + vec2f(0.0, -radius), + radius, + ); + path.arc_to(rect.origin(), rect.origin() + vec2f(radius, 0.0), radius); path.close_path(); path } @@ -1470,16 +1755,19 @@ fn main() { let mut event_loop = EventLoop::new(); let window_size = Size2D::new(WINDOW_WIDTH, WINDOW_HEIGHT); let logical_size = LogicalSize::new(window_size.width as f64, window_size.height as f64); - let window = WindowBuilder::new().with_title("NanoVG example port") - .with_inner_size(logical_size) - .build(&event_loop) - .unwrap(); + let window = WindowBuilder::new() + .with_title("NanoVG example port") + .with_inner_size(logical_size) + .build(&event_loop) + .unwrap(); // window.show(); // Create a `surfman` device. On a multi-GPU system, we'll request the low-power integrated // GPU. let connection = Connection::from_winit_window(&window).unwrap(); - let native_widget = connection.create_native_widget_from_winit_window(&window).unwrap(); + let native_widget = connection + .create_native_widget_from_winit_window(&window) + .unwrap(); let adapter = connection.create_low_power_adapter().unwrap(); let mut device = connection.create_device(&adapter).unwrap(); @@ -1488,14 +1776,19 @@ fn main() { version: SurfmanGLVersion::new(3, 0), flags: ContextAttributeFlags::ALPHA, }; - let context_descriptor = device.create_context_descriptor(&context_attributes).unwrap(); + let context_descriptor = device + .create_context_descriptor(&context_attributes) + .unwrap(); // Make the OpenGL context via `surfman`, and load OpenGL functions. let surface_type = SurfaceType::Widget { native_widget }; let mut gl_context = device.create_context(&context_descriptor, None).unwrap(); - let surface = device.create_surface(&gl_context, SurfaceAccess::GPUOnly, surface_type) - .unwrap(); - device.bind_surface_to_context(&mut gl_context, surface).unwrap(); + let surface = device + .create_surface(&gl_context, SurfaceAccess::GPUOnly, surface_type) + .unwrap(); + device + .bind_surface_to_context(&mut gl_context, surface) + .unwrap(); device.make_context_current(&gl_context).unwrap(); gl::load_with(|symbol_name| device.get_proc_address(&gl_context, symbol_name)); @@ -1507,17 +1800,27 @@ fn main() { // Load demo data. let resources = FilesystemResourceLoader::locate(); let font_data = vec![ - Handle::from_memory(Arc::new(resources.slurp("fonts/Roboto-Regular.ttf").unwrap()), 0), - Handle::from_memory(Arc::new(resources.slurp("fonts/Roboto-Bold.ttf").unwrap()), 0), - Handle::from_memory(Arc::new(resources.slurp("fonts/NotoEmoji-Regular.ttf").unwrap()), 0), + Handle::from_memory( + Arc::new(resources.slurp("fonts/Roboto-Regular.ttf").unwrap()), + 0, + ), + Handle::from_memory( + Arc::new(resources.slurp("fonts/Roboto-Bold.ttf").unwrap()), + 0, + ), + Handle::from_memory( + Arc::new(resources.slurp("fonts/NotoEmoji-Regular.ttf").unwrap()), + 0, + ), ]; let demo_data = DemoData::load(&resources); // Create a Pathfinder GL device. - let default_framebuffer = device.context_surface_info(&gl_context) - .unwrap() - .unwrap() - .framebuffer_object; + let default_framebuffer = device + .context_surface_info(&gl_context) + .unwrap() + .unwrap() + .framebuffer_object; let pathfinder_device = GLDevice::new(GLVersion::GL3, default_framebuffer); // Create a Pathfinder renderer. @@ -1527,10 +1830,12 @@ fn main() { dest: DestFramebuffer::full_window(framebuffer_size), ..RendererOptions::default() }; - let mut renderer = Renderer::new(pathfinder_device, - &resources, - renderer_mode, - renderer_options); + let mut renderer = Renderer::new( + pathfinder_device, + &resources, + renderer_mode, + renderer_options, + ); // Initialize font state. let font_source = Arc::new(MemSource::from_fonts(font_data.into_iter()).unwrap()); @@ -1561,12 +1866,14 @@ fn main() { // Render the demo. context.scale(hidpi_factor as f32); - render_demo(&mut context, - mouse_position, - vec2f(WINDOW_WIDTH as f32, WINDOW_HEIGHT as f32), - frame_start_elapsed_time, - hidpi_factor as f32, - &demo_data); + render_demo( + &mut context, + mouse_position, + vec2f(WINDOW_WIDTH as f32, WINDOW_HEIGHT as f32), + frame_start_elapsed_time, + hidpi_factor as f32, + &demo_data, + ); // Render performance graphs. let cpu_frame_elapsed_time = (Instant::now() - frame_start_time).as_secs_f32(); @@ -1580,9 +1887,16 @@ fn main() { scene.build_and_render(&mut renderer, BuildOptions::default()); // Present the rendered canvas via `surfman`. - let mut surface = device.unbind_surface_from_context(&mut gl_context).unwrap().unwrap(); - device.present_surface(&mut gl_context, &mut surface).unwrap(); - device.bind_surface_to_context(&mut gl_context, surface).unwrap(); + let mut surface = device + .unbind_surface_from_context(&mut gl_context) + .unwrap() + .unwrap(); + device + .present_surface(&mut gl_context, &mut surface) + .unwrap(); + device + .bind_surface_to_context(&mut gl_context, surface) + .unwrap(); // Add stats to performance graphs. if let Some(gpu_time) = renderer.last_rendering_time() { @@ -1593,22 +1907,31 @@ fn main() { gpu_graph.push(gpu_time); } - event_loop.run_return(|event,_, control| { - match event { - Event::WindowEvent { event: WindowEvent::CloseRequested, .. } | - Event::WindowEvent { - event: WindowEvent::KeyboardInput { - input: KeyboardInput { virtual_keycode: Some(VirtualKeyCode::Escape), .. }, + event_loop.run_return(|event, _, control| match event { + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } + | Event::WindowEvent { + event: + WindowEvent::KeyboardInput { + input: + KeyboardInput { + virtual_keycode: Some(VirtualKeyCode::Escape), + .. + }, .. }, - .. - } => exit = true, - Event::WindowEvent { event: WindowEvent::CursorMoved { position, .. }, .. } => { - mouse_position = vec2f(position.x as f32, position.y as f32); - } - _ => { - *control = ControlFlow::Exit; - } + .. + } => exit = true, + Event::WindowEvent { + event: WindowEvent::CursorMoved { position, .. }, + .. + } => { + mouse_position = vec2f(position.x as f32, position.y as f32); + } + _ => { + *control = ControlFlow::Exit; } }); } diff --git a/examples/canvas_text/Cargo.toml b/examples/canvas_text/Cargo.toml index dad3dbec..325147bf 100644 --- a/examples/canvas_text/Cargo.toml +++ b/examples/canvas_text/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Patrick Walton "] edition = "2018" [dependencies] -font-kit = "0.6" +font-kit = "0.13" gl = "0.14" sdl2 = "0.33" sdl2-sys = "0.33" diff --git a/examples/canvas_text/src/main.rs b/examples/canvas_text/src/main.rs index 6e8f560b..799c72de 100644 --- a/examples/canvas_text/src/main.rs +++ b/examples/canvas_text/src/main.rs @@ -18,8 +18,8 @@ use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererMode, RendererOptions}; use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::options::BuildOptions; -use pathfinder_resources::ResourceLoader; use pathfinder_resources::fs::FilesystemResourceLoader; +use pathfinder_resources::ResourceLoader; use sdl2::event::{Event, WindowEvent}; use sdl2::keyboard::Keycode; use sdl2::video::GLProfile; @@ -36,16 +36,19 @@ fn main() { let gl_attributes = video.gl_attr(); gl_attributes.set_context_profile(GLProfile::Core); gl_attributes.set_context_version(4, 1); - gl_attributes.set_context_flags() - .forward_compatible() - .set(); + gl_attributes.set_context_flags().forward_compatible().set(); // Open a window. let window_size = vec2i(640, 480); - let window = video.window("Text example", window_size.x() as u32, window_size.y() as u32) - .opengl() - .build() - .unwrap(); + let window = video + .window( + "Text example", + window_size.x() as u32, + window_size.y() as u32, + ) + .opengl() + .build() + .unwrap(); // Create the GL context, and make it current. let gl_context = window.gl_create_context().unwrap(); @@ -75,10 +78,21 @@ fn main() { let mut fps_buf = String::new(); loop { match event_pump.poll_event() { - Some(Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. }) => return, - Some(Event::Window { win_event: WindowEvent::Exposed, .. }) | None => { + Some( + Event::Quit { .. } + | Event::KeyDown { + keycode: Some(Keycode::Escape), + .. + }, + ) => return, + Some(Event::Window { + win_event: WindowEvent::Exposed, + .. + }) + | None => { // Make a canvas. - let mut canvas = Canvas::new(window_size.to_f32()).get_context_2d(font_context.clone()); + let mut canvas = + Canvas::new(window_size.to_f32()).get_context_2d(font_context.clone()); // Draw the text. canvas.set_font("Overpass-Regular").unwrap(); @@ -87,7 +101,9 @@ fn main() { let elapsed = now.duration_since(last_update); if elapsed >= Duration::from_millis(50) { last_update = now; - let fps = (n as f64) * ((Duration::from_secs(1).as_micros() as f64) / (elapsed.as_micros() as f64)); + let fps = (n as f64) + * ((Duration::from_secs(1).as_micros() as f64) + / (elapsed.as_micros() as f64)); fps_buf.clear(); fps_buf.push_str("FPS: "); use std::fmt::Write; @@ -100,14 +116,16 @@ fn main() { canvas.stroke_text("Goodbye Pathfinder!", vec2f(608.0, 464.0)); // Render the canvas to screen. - let mut scene = SceneProxy::from_scene(canvas.into_canvas().into_scene(), - renderer.mode().level, - RayonExecutor); + let mut scene = SceneProxy::from_scene( + canvas.into_canvas().into_scene(), + renderer.mode().level, + RayonExecutor, + ); scene.build_and_render(&mut renderer, BuildOptions::default()); window.gl_swap_window(); n += 1; - }, + } _ => {} } } diff --git a/examples/canvas_webgl_minimal/src/lib.rs b/examples/canvas_webgl_minimal/src/lib.rs index bfa17b37..f3598dc1 100644 --- a/examples/canvas_webgl_minimal/src/lib.rs +++ b/examples/canvas_webgl_minimal/src/lib.rs @@ -18,8 +18,8 @@ use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::options::BuildOptions; use pathfinder_resources::embedded::EmbeddedResourceLoader; use pathfinder_webgl::WebGlDevice; -use wasm_bindgen::JsCast; use wasm_bindgen::prelude::*; +use wasm_bindgen::JsCast; use web_sys::{self, HtmlCanvasElement, WebGl2RenderingContext}; mod utils; @@ -32,11 +32,12 @@ pub fn rust_main() { let canvas = document.get_element_by_id("c").unwrap(); let canvas: HtmlCanvasElement = canvas.dyn_into::().unwrap(); - let context = canvas.get_context("webgl2") - .unwrap() - .unwrap() - .dyn_into::() - .unwrap(); + let context = canvas + .get_context("webgl2") + .unwrap() + .unwrap() + .dyn_into::() + .unwrap(); // Get the real size of the window, taking HiDPI into account. let framebuffer_size = vec2i(canvas.width() as i32, canvas.height() as i32); diff --git a/examples/swf_basic/src/main.rs b/examples/swf_basic/src/main.rs index 8be646af..4277f2ab 100644 --- a/examples/swf_basic/src/main.rs +++ b/examples/swf_basic/src/main.rs @@ -10,20 +10,20 @@ use pathfinder_geometry::rect::RectF; use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::vector::{Vector2F, vec2f, vec2i}; +use pathfinder_geometry::vector::{vec2f, vec2i, Vector2F}; use pathfinder_gl::{GLDevice, GLVersion}; use pathfinder_renderer::concurrent::rayon::RayonExecutor; use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; -use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererMode, RendererOptions}; -use pathfinder_renderer::options::{RenderTransform, BuildOptions}; -use pathfinder_resources::ResourceLoader; +use pathfinder_renderer::gpu::renderer::Renderer; +use pathfinder_renderer::options::{BuildOptions, RenderTransform}; +use pathfinder_renderer::scene::Scene; use pathfinder_resources::embedded::EmbeddedResourceLoader; +use pathfinder_resources::ResourceLoader; +use pathfinder_swf::{draw_paths_into_scene, process_swf_tags}; use sdl2::event::Event; use sdl2::keyboard::Keycode; use sdl2::video::GLProfile; -use pathfinder_renderer::scene::Scene; -use pathfinder_swf::{draw_paths_into_scene, process_swf_tags}; use std::env; use std::fs::read; @@ -35,8 +35,8 @@ fn main() { match read(path) { Ok(bytes) => { swf_bytes = bytes; - }, - Err(e) => panic!("{}", e) + } + Err(e) => panic!("{}", e), } } else { // NOTE(jon): This is a version of the ghostscript tiger graphic flattened to a single @@ -83,13 +83,21 @@ fn main() { // Open a window. let window_size = vec2i(stage.width(), stage.height()); - let window = video.window("Minimal example", window_size.x() as u32, window_size.y() as u32) + let window = video + .window( + "Minimal example", + window_size.x() as u32, + window_size.y() as u32, + ) .opengl() .allow_highdpi() .build() .unwrap(); - let pixel_size = vec2i(window.drawable_size().0 as i32, window.drawable_size().1 as i32); + let pixel_size = vec2i( + window.drawable_size().0 as i32, + window.drawable_size().1 as i32, + ); let device_pixel_ratio = pixel_size.x() as f32 / window_size.x() as f32; // Create the GL context, and make it current. @@ -109,9 +117,10 @@ fn main() { // Clear to swf stage background color. let mut scene = Scene::new(); - scene.set_view_box(RectF::new(Vector2F::zero(), - vec2f(stage.width() as f32, - stage.height() as f32) * device_pixel_ratio)); + scene.set_view_box(RectF::new( + Vector2F::zero(), + vec2f(stage.width() as f32, stage.height() as f32) * device_pixel_ratio, + )); draw_paths_into_scene(&library, &mut scene); // Render the canvas to screen. @@ -126,7 +135,11 @@ fn main() { let mut event_pump = sdl_context.event_pump().unwrap(); loop { match event_pump.wait_event() { - Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => return, + Event::Quit { .. } + | Event::KeyDown { + keycode: Some(Keycode::Escape), + .. + } => return, _ => {} } } diff --git a/export/src/lib.rs b/export/src/lib.rs index c2957610..313c5f32 100644 --- a/export/src/lib.rs +++ b/export/src/lib.rs @@ -10,7 +10,7 @@ use pathfinder_content::outline::ContourIterFlags; use pathfinder_content::segment::SegmentKind; -use pathfinder_geometry::vector::{Vector2F, vec2f}; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use pathfinder_renderer::scene::{DrawPathId, Scene}; use std::fmt; use std::io::{self, Write}; @@ -39,7 +39,7 @@ impl Export for Scene { match format { FileFormat::SVG => export_svg(self, writer), FileFormat::PDF => export_pdf(self, writer), - FileFormat::PS => export_ps(self, writer) + FileFormat::PS => export_ps(self, writer), } } } @@ -63,7 +63,12 @@ fn export_svg(scene: &Scene, writer: &mut W) -> io::Result<()> { if !draw_path.name.is_empty() { write!(writer, " id=\"{}\"", draw_path.name)?; } - writeln!(writer, " fill=\"{:?}\" d=\"{:?}\" />", paint.base_color(), draw_path.outline)?; + writeln!( + writer, + " fill=\"{:?}\" d=\"{:?}\" />", + paint.base_color(), + draw_path.outline + )?; } writeln!(writer, "")?; Ok(()) @@ -107,11 +112,11 @@ fn export_pdf(scene: &Scene, writer: &mut W) -> io::Result<()> { 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())) - } + SegmentKind::Cubic => pdf.cubic_to( + tr(segment.ctrl.from()), + tr(segment.ctrl.to()), + tr(segment.baseline.to()), + ), } } @@ -136,11 +141,15 @@ fn export_ps(scene: &Scene, writer: &mut W) -> io::Result<()> { let view_box = scene.view_box(); writeln!(writer, "%!PS-Adobe-3.0 EPSF-3.0")?; - writeln!(writer, "%%BoundingBox: {:.0} {:.0}", + writeln!( + writer, + "%%BoundingBox: {:.0} {:.0}", P(view_box.origin()), P(view_box.size()), )?; - writeln!(writer, "%%HiResBoundingBox: {} {}", + writeln!( + writer, + "%%HiResBoundingBox: {} {}", P(view_box.origin()), P(view_box.size()), )?; @@ -176,7 +185,9 @@ fn export_ps(scene: &Scene, writer: &mut W) -> io::Result<()> { writeln!(writer, "{} {} {} curveto", P(c1), P(c2), P(p))?; } SegmentKind::Cubic => { - writeln!(writer, "{} {} {} curveto", + writeln!( + writer, + "{} {} {} curveto", P(segment.ctrl.from()), P(segment.ctrl.to()), P(segment.baseline.to()) @@ -202,5 +213,3 @@ fn export_ps(scene: &Scene, writer: &mut W) -> io::Result<()> { writeln!(writer, "showpage")?; Ok(()) } - - diff --git a/export/src/pdf.rs b/export/src/pdf.rs index bb85344b..0f90ca11 100644 --- a/export/src/pdf.rs +++ b/export/src/pdf.rs @@ -18,14 +18,11 @@ use std::io::{self, Write}; struct Counter { inner: T, - count: u64 + count: u64, } impl Counter { pub fn new(inner: T) -> Counter { - Counter { - inner, - count: 0 - } + Counter { inner, count: 0 } } pub fn pos(&self) -> u64 { self.count @@ -37,8 +34,8 @@ impl Write for Counter { Ok(n) => { self.count += n as u64; Ok(n) - }, - Err(e) => Err(e) + } + Err(e) => Err(e), } } fn flush(&mut self) -> io::Result<()> { @@ -95,7 +92,7 @@ impl Pdf { }, ], page_size: None, - compression: Some(Compression::Fast) + compression: Some(Compression::Fast), } } @@ -113,11 +110,14 @@ impl Pdf { #[inline] pub fn set_fill_color(&mut self, color: ColorU) { let norm = |color| f32::from(color) / 255.0; - writeln!(self.page_buffer, "{} {} {} rg", + writeln!( + self.page_buffer, + "{} {} {} rg", norm(color.r), norm(color.g), norm(color.b) - ).unwrap(); + ) + .unwrap(); } /// Move to a new page in the PDF document @@ -134,7 +134,7 @@ impl Pdf { self.page_size = Some(size); } - pub fn move_to(&mut self, p: Vector2F) { + pub fn move_to(&mut self, p: Vector2F) { writeln!(self.page_buffer, "{} {} m", p.x(), p.y()).unwrap(); } @@ -143,7 +143,17 @@ impl Pdf { } 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(); + 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(); @@ -156,7 +166,7 @@ impl Pdf { fn end_page(&mut self) { let size = match self.page_size.take() { Some(size) => size, - None => return // no page started + 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); @@ -185,22 +195,31 @@ impl Pdf { /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(); + 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(); + 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 { + 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")?; @@ -211,7 +230,7 @@ impl Pdf { // 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)?; + write!(out, "{} 0 obj\n", idx + 1)?; out.write_all(&obj.contents)?; out.write_all(b"endobj\n")?; } @@ -220,12 +239,18 @@ impl Pdf { self.objects[1].offset = Some(out.pos()); out.write_all(b"2 0 obj\n")?; out.write_all(b"<< /Type /Pages\n")?; - write!(out, + 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) { + 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")?; diff --git a/geometry/src/line_segment.rs b/geometry/src/line_segment.rs index aed60bb9..c086066a 100644 --- a/geometry/src/line_segment.rs +++ b/geometry/src/line_segment.rs @@ -12,7 +12,7 @@ use crate::transform2d::Matrix2x2F; use crate::util; -use crate::vector::{Vector2F, vec2f}; +use crate::vector::{vec2f, Vector2F}; use pathfinder_simd::default::F32x4; use std::ops::{Add, Mul, MulAssign, Sub}; diff --git a/geometry/src/rect.rs b/geometry/src/rect.rs index 34a988e7..436faac3 100644 --- a/geometry/src/rect.rs +++ b/geometry/src/rect.rs @@ -91,13 +91,19 @@ impl RectF { 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() + 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() + self.0 + .concat_xy_zw(other.0) + .packed_le(other.0.concat_xy_zw(self.0)) + .all_true() } #[inline] @@ -121,7 +127,10 @@ impl RectF { #[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() + self.0 + .concat_xy_xy(other.0) + .packed_lt(other.0.concat_zw_zw(self.0)) + .all_true() } #[inline] @@ -173,13 +182,19 @@ impl RectF { } #[inline] - pub fn dilate(self, amount: A) -> RectF where A: IntoVector2F { + 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 { + 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) } @@ -380,7 +395,10 @@ impl RectI { #[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() + self.0 + .concat_xy_xy(other.0) + .packed_lt(other.0.concat_zw_zw(self.0)) + .all_true() } #[inline] diff --git a/geometry/src/transform2d.rs b/geometry/src/transform2d.rs index c29ae7b9..91b5cc01 100644 --- a/geometry/src/transform2d.rs +++ b/geometry/src/transform2d.rs @@ -14,7 +14,7 @@ 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 crate::vector::{vec2f, IntoVector2F, Vector2F}; use pathfinder_simd::default::F32x4; use std::ops::{Mul, MulAssign, Sub}; @@ -31,7 +31,10 @@ impl Default for Matrix2x2F { impl Matrix2x2F { #[inline] - pub fn from_scale(scale: S) -> Matrix2x2F where S: IntoVector2F { + 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())) } @@ -145,7 +148,10 @@ impl Default for Transform2F { impl Transform2F { #[inline] - pub fn from_scale(scale: S) -> Transform2F where S: IntoVector2F { + pub fn from_scale(scale: S) -> Transform2F + where + S: IntoVector2F, + { let scale = scale.into_vector_2f(); Transform2F { matrix: Matrix2x2F::from_scale(scale), @@ -171,12 +177,21 @@ impl Transform2F { #[inline] pub fn from_translation(vector: Vector2F) -> Transform2F { - Transform2F { matrix: Matrix2x2F::default(), vector } + Transform2F { + matrix: Matrix2x2F::default(), + vector, + } } #[inline] - pub fn from_scale_rotation_translation(scale: S, theta: f32, translation: Vector2F) - -> Transform2F where S: IntoVector2F { + 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); @@ -261,7 +276,10 @@ impl Transform2F { } #[inline] - pub fn scale(&self, scale: S) -> Transform2F where S: IntoVector2F { + pub fn scale(&self, scale: S) -> Transform2F + where + S: IntoVector2F, + { let scale = scale.into_vector_2f(); Transform2F::from_scale(scale) * *self } @@ -294,7 +312,10 @@ impl Transform2F { 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 } + Transform2F { + matrix: matrix_inv, + vector: vector_inv, + } } } @@ -329,7 +350,7 @@ 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 (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); diff --git a/geometry/src/transform3d.rs b/geometry/src/transform3d.rs index 94d36485..013fc564 100644 --- a/geometry/src/transform3d.rs +++ b/geometry/src/transform3d.rs @@ -74,7 +74,7 @@ impl 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), + c3: F32x4::new(0.0, 0.0, 0.0, 1.0), } } @@ -86,7 +86,10 @@ impl Transform4F { #[inline] pub fn from_translation(mut translation: Vector4F) -> Transform4F { translation.set_w(1.0); - Transform4F { c3: translation.0, ..Transform4F::default() } + Transform4F { + c3: translation.0, + ..Transform4F::default() + } } // TODO(pcwalton): Optimize. @@ -212,11 +215,24 @@ impl Transform4F { // 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()); + 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 } @@ -415,7 +431,7 @@ 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 (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); @@ -425,8 +441,8 @@ impl Mul for Perspective { #[cfg(test)] mod test { - use crate::vector::Vector4F; use crate::transform3d::Transform4F; + use crate::vector::Vector4F; #[test] fn test_post_mul() { diff --git a/geometry/src/unit_vector.rs b/geometry/src/unit_vector.rs index 5a36d1d1..78066468 100644 --- a/geometry/src/unit_vector.rs +++ b/geometry/src/unit_vector.rs @@ -26,14 +26,20 @@ impl UnitVector { #[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])) + 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])) + UnitVector(Vector2F::new( + products[0] + products[1], + products[2] - products[3], + )) } /// Half angle formula. @@ -41,7 +47,10 @@ impl UnitVector { 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())) + UnitVector(Vector2F( + (F32x2::splat(0.5) * (F32x2::splat(1.0) + term)) + .max(F32x2::default()) + .sqrt(), + )) } } diff --git a/geometry/src/vector.rs b/geometry/src/vector.rs index fa864f5d..07a67a19 100644 --- a/geometry/src/vector.rs +++ b/geometry/src/vector.rs @@ -36,12 +36,20 @@ impl Vector2F { #[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))) + 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))) + Vector4F( + self.0 + .to_f32x4() + .concat_xy_zw(F32x4::new(0.0, 0.0, 0.0, 1.0)), + ) } #[inline] @@ -294,9 +302,9 @@ impl Neg for Vector2F { } /// 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 { @@ -458,7 +466,10 @@ impl Eq for Vector2I {} impl Hash for Vector2I { #[inline] - fn hash(&self, state: &mut H) where H: Hasher { + fn hash(&self, state: &mut H) + where + H: Hasher, + { self.x().hash(state); self.y().hash(state); } diff --git a/gl/src/lib.rs b/gl/src/lib.rs index 007bb85d..e114d8cc 100644 --- a/gl/src/lib.rs +++ b/gl/src/lib.rs @@ -22,7 +22,9 @@ use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploa use pathfinder_gpu::{ComputeDimensions, ComputeState, DepthFunc, Device, FeatureLevel}; use pathfinder_gpu::{ImageAccess, ImageBinding, Primitive, ProgramKind, RenderOptions}; use pathfinder_gpu::{RenderState, RenderTarget, ShaderKind, StencilFunc, TextureBinding}; -use pathfinder_gpu::{TextureData, TextureDataRef, TextureFormat, TextureSamplingFlags, UniformData}; +use pathfinder_gpu::{ + TextureData, TextureDataRef, TextureFormat, TextureSamplingFlags, UniformData, +}; use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; use pathfinder_resources::ResourceLoader; use pathfinder_simd::default::F32x4; @@ -53,13 +55,18 @@ impl GLDevice { format: TextureFormat::RGBA8, }; - let mut device = GLDevice { version, default_framebuffer, dummy_texture }; + let mut device = GLDevice { + version, + default_framebuffer, + dummy_texture, + }; let dummy_texture_data = [0; DUMMY_TEXTURE_LENGTH as usize * DUMMY_TEXTURE_LENGTH as usize * 4]; - device.dummy_texture = - device.create_texture_from_data(TextureFormat::RGBA8, - Vector2I::splat(DUMMY_TEXTURE_LENGTH), - TextureDataRef::U8(&dummy_texture_data)); + device.dummy_texture = device.create_texture_from_data( + TextureFormat::RGBA8, + Vector2I::splat(DUMMY_TEXTURE_LENGTH), + TextureDataRef::U8(&dummy_texture_data), + ); device } @@ -82,15 +89,20 @@ impl GLDevice { self.use_program(render_state.program); self.bind_vertex_array(render_state.vertex_array); - self.bind_textures_and_images(&render_state.program, - &render_state.textures, - &render_state.images); + self.bind_textures_and_images( + &render_state.program, + &render_state.textures, + &render_state.images, + ); for &(storage_buffer, buffer) in render_state.storage_buffers { self.set_storage_buffer(storage_buffer, buffer); } - render_state.uniforms.iter().for_each(|(uniform, data)| self.set_uniform(uniform, data)); + render_state + .uniforms + .iter() + .for_each(|(uniform, data)| self.set_uniform(uniform, data)); self.set_render_options(&render_state.options); } @@ -98,21 +110,28 @@ impl GLDevice { fn set_compute_state(&self, compute_state: &ComputeState) { self.use_program(compute_state.program); - self.bind_textures_and_images(&compute_state.program, - &compute_state.textures, - &compute_state.images); + self.bind_textures_and_images( + &compute_state.program, + &compute_state.textures, + &compute_state.images, + ); - compute_state.uniforms.iter().for_each(|(uniform, data)| self.set_uniform(uniform, data)); + compute_state + .uniforms + .iter() + .for_each(|(uniform, data)| self.set_uniform(uniform, data)); for &(storage_buffer, buffer) in compute_state.storage_buffers { self.set_storage_buffer(storage_buffer, buffer); } } - fn bind_textures_and_images(&self, - program: &GLProgram, - texture_bindings: &[TextureBinding], - image_bindings: &[ImageBinding]) { + fn bind_textures_and_images( + &self, + program: &GLProgram, + texture_bindings: &[TextureBinding], + image_bindings: &[ImageBinding], + ) { let (mut textures_bound, mut images_bound) = (0, 0); for &(texture_parameter, texture) in texture_bindings { self.bind_texture(texture, texture_parameter.texture_unit); @@ -129,19 +148,24 @@ impl GLDevice { if (textures_bound & (1 << texture_unit as u64)) == 0 { self.bind_texture(&self.dummy_texture, texture_unit as GLuint); } - gl::Uniform1i(uniform.location, texture_unit as GLint); ck(); + gl::Uniform1i(uniform.location, texture_unit as GLint); + ck(); } for (image_unit, uniform) in parameters.images.iter().enumerate() { if (images_bound & (1 << image_unit as u64)) == 0 { - gl::BindImageTexture(image_unit as GLuint, - self.dummy_texture.gl_texture, - 0, - gl::FALSE, - 0, - gl::READ_ONLY, - gl::RGBA8 as GLenum); ck(); + gl::BindImageTexture( + image_unit as GLuint, + self.dummy_texture.gl_texture, + 0, + gl::FALSE, + 0, + gl::READ_ONLY, + gl::RGBA8 as GLenum, + ); + ck(); } - gl::Uniform1i(uniform.location, image_unit as GLint); ck(); + gl::Uniform1i(uniform.location, image_unit as GLint); + ck(); } } } @@ -151,53 +175,70 @@ impl GLDevice { // Set blend. match render_options.blend { None => { - gl::Disable(gl::BLEND); ck(); + gl::Disable(gl::BLEND); + ck(); } Some(ref blend) => { - gl::BlendFuncSeparate(blend.src_rgb_factor.to_gl_blend_factor(), - blend.dest_rgb_factor.to_gl_blend_factor(), - blend.src_alpha_factor.to_gl_blend_factor(), - blend.dest_alpha_factor.to_gl_blend_factor()); ck(); - gl::BlendEquation(blend.op.to_gl_blend_op()); ck(); - gl::Enable(gl::BLEND); ck(); + gl::BlendFuncSeparate( + blend.src_rgb_factor.to_gl_blend_factor(), + blend.dest_rgb_factor.to_gl_blend_factor(), + blend.src_alpha_factor.to_gl_blend_factor(), + blend.dest_alpha_factor.to_gl_blend_factor(), + ); + ck(); + gl::BlendEquation(blend.op.to_gl_blend_op()); + ck(); + gl::Enable(gl::BLEND); + ck(); } } // Set depth. match render_options.depth { None => { - gl::Disable(gl::DEPTH_TEST); ck(); + gl::Disable(gl::DEPTH_TEST); + ck(); } Some(ref state) => { - gl::DepthFunc(state.func.to_gl_depth_func()); ck(); - gl::DepthMask(state.write as GLboolean); ck(); - gl::Enable(gl::DEPTH_TEST); ck(); + gl::DepthFunc(state.func.to_gl_depth_func()); + ck(); + gl::DepthMask(state.write as GLboolean); + ck(); + gl::Enable(gl::DEPTH_TEST); + ck(); } } // Set stencil. match render_options.stencil { None => { - gl::Disable(gl::STENCIL_TEST); ck(); + gl::Disable(gl::STENCIL_TEST); + ck(); } Some(ref state) => { - gl::StencilFunc(state.func.to_gl_stencil_func(), - state.reference as GLint, - state.mask); ck(); + gl::StencilFunc( + state.func.to_gl_stencil_func(), + state.reference as GLint, + state.mask, + ); + ck(); let (pass_action, write_mask) = if state.write { (gl::REPLACE, state.mask) } else { (gl::KEEP, 0) }; - gl::StencilOp(gl::KEEP, gl::KEEP, pass_action); ck(); + gl::StencilOp(gl::KEEP, gl::KEEP, pass_action); + ck(); gl::StencilMask(write_mask); - gl::Enable(gl::STENCIL_TEST); ck(); + gl::Enable(gl::STENCIL_TEST); + ck(); } } // Set color mask. let color_mask = render_options.color_mask as GLboolean; - gl::ColorMask(color_mask, color_mask, color_mask, color_mask); ck(); + gl::ColorMask(color_mask, color_mask, color_mask, color_mask); + ck(); } } @@ -205,40 +246,51 @@ impl GLDevice { unsafe { match *data { UniformData::Float(value) => { - gl::Uniform1f(uniform.location, value); ck(); + gl::Uniform1f(uniform.location, value); + ck(); } UniformData::IVec2(value) => { - gl::Uniform2i(uniform.location, value[0], value[1]); ck(); + gl::Uniform2i(uniform.location, value[0], value[1]); + ck(); } UniformData::IVec3(value) => { - gl::Uniform3i(uniform.location, value[0], value[1], value[2]); ck(); + gl::Uniform3i(uniform.location, value[0], value[1], value[2]); + ck(); } UniformData::Int(value) => { - gl::Uniform1i(uniform.location, value); ck(); + gl::Uniform1i(uniform.location, value); + ck(); } UniformData::Mat2(data) => { assert_eq!(mem::size_of::(), 4 * 4); - gl::UniformMatrix2fv(uniform.location, - 1, - gl::FALSE, - &data as *const F32x4 as *const GLfloat); + gl::UniformMatrix2fv( + uniform.location, + 1, + gl::FALSE, + &data as *const F32x4 as *const GLfloat, + ); } UniformData::Mat4(data) => { assert_eq!(mem::size_of::<[F32x4; 4]>(), 4 * 4 * 4); let data_ptr: *const F32x4 = data.as_ptr(); - gl::UniformMatrix4fv(uniform.location, - 1, - gl::FALSE, - data_ptr as *const GLfloat); + gl::UniformMatrix4fv( + uniform.location, + 1, + gl::FALSE, + data_ptr as *const GLfloat, + ); } UniformData::Vec2(data) => { - gl::Uniform2f(uniform.location, data.x(), data.y()); ck(); + gl::Uniform2f(uniform.location, data.x(), data.y()); + ck(); } UniformData::Vec3(data) => { - gl::Uniform3f(uniform.location, data[0], data[1], data[2]); ck(); + gl::Uniform3f(uniform.location, data[0], data[1], data[2]); + ck(); } UniformData::Vec4(data) => { - gl::Uniform4f(uniform.location, data.x(), data.y(), data.z(), data.w()); ck(); + gl::Uniform4f(uniform.location, data.x(), data.y(), data.z(), data.w()); + ck(); } } } @@ -246,15 +298,21 @@ impl GLDevice { fn set_storage_buffer(&self, storage_buffer: &GLStorageBuffer, buffer: &GLBuffer) { unsafe { - gl::BindBufferBase(gl::SHADER_STORAGE_BUFFER, - storage_buffer.location as GLuint, - buffer.object.gl_buffer); + gl::BindBufferBase( + gl::SHADER_STORAGE_BUFFER, + storage_buffer.location as GLuint, + buffer.object.gl_buffer, + ); } } fn unset_storage_buffer(&self, storage_buffer: &GLStorageBuffer) { unsafe { - gl::BindBufferBase(gl::SHADER_STORAGE_BUFFER, storage_buffer.location as GLuint, 0); + gl::BindBufferBase( + gl::SHADER_STORAGE_BUFFER, + storage_buffer.location as GLuint, + 0, + ); } } @@ -268,11 +326,13 @@ impl GLDevice { unsafe { for image_binding in render_state.images { self.unbind_image(image_binding.0.image_unit); - gl::Uniform1i(image_binding.0.uniform.location, 0); ck(); + gl::Uniform1i(image_binding.0.uniform.location, 0); + ck(); } for texture_binding in render_state.textures { self.unbind_texture(texture_binding.0.texture_unit); - gl::Uniform1i(texture_binding.0.uniform.location, 0); ck(); + gl::Uniform1i(texture_binding.0.uniform.location, 0); + ck(); } } @@ -288,11 +348,13 @@ impl GLDevice { unsafe { for image_binding in compute_state.images { self.unbind_image(image_binding.0.image_unit); - gl::Uniform1i(image_binding.0.uniform.location, 0); ck(); + gl::Uniform1i(image_binding.0.uniform.location, 0); + ck(); } for texture_binding in compute_state.textures { self.unbind_texture(texture_binding.0.texture_unit); - gl::Uniform1i(texture_binding.0.uniform.location, 0); ck(); + gl::Uniform1i(texture_binding.0.uniform.location, 0); + ck(); } } @@ -302,19 +364,24 @@ impl GLDevice { fn reset_render_options(&self, render_options: &RenderOptions) { unsafe { if render_options.blend.is_some() { - gl::Disable(gl::BLEND); ck(); + gl::Disable(gl::BLEND); + ck(); } if render_options.depth.is_some() { - gl::Disable(gl::DEPTH_TEST); ck(); + gl::Disable(gl::DEPTH_TEST); + ck(); } if render_options.stencil.is_some() { - gl::StencilMask(!0); ck(); - gl::Disable(gl::STENCIL_TEST); ck(); + gl::StencilMask(!0); + ck(); + gl::Disable(gl::STENCIL_TEST); + ck(); } - gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); ck(); + gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); + ck(); } } } @@ -344,8 +411,9 @@ impl Device for GLDevice { #[inline] fn device_name(&self) -> String { unsafe { - CStr::from_ptr(gl::GetString(gl::RENDERER) as *const c_char).to_string_lossy() - .to_string() + CStr::from_ptr(gl::GetString(gl::RENDERER) as *const c_char) + .to_string_lossy() + .to_string() } } @@ -357,41 +425,60 @@ impl Device for GLDevice { } fn create_texture(&self, format: TextureFormat, size: Vector2I) -> GLTexture { - let mut texture = GLTexture { gl_texture: 0, size, format }; + let mut texture = GLTexture { + gl_texture: 0, + size, + format, + }; unsafe { - gl::GenTextures(1, &mut texture.gl_texture); ck(); + gl::GenTextures(1, &mut texture.gl_texture); + ck(); self.bind_texture(&texture, 0); - gl::TexImage2D(gl::TEXTURE_2D, - 0, - format.gl_internal_format(), - size.x() as GLsizei, - size.y() as GLsizei, - 0, - format.gl_format(), - format.gl_type(), - ptr::null()); ck(); + gl::TexImage2D( + gl::TEXTURE_2D, + 0, + format.gl_internal_format(), + size.x() as GLsizei, + size.y() as GLsizei, + 0, + format.gl_format(), + format.gl_type(), + ptr::null(), + ); + ck(); } self.set_texture_sampling_mode(&texture, TextureSamplingFlags::empty()); texture } - fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef) - -> GLTexture { + fn create_texture_from_data( + &self, + format: TextureFormat, + size: Vector2I, + data: TextureDataRef, + ) -> GLTexture { let data_ptr = data.check_and_extract_data_ptr(size, format); - let mut texture = GLTexture { gl_texture: 0, size, format: TextureFormat::R8 }; + let mut texture = GLTexture { + gl_texture: 0, + size, + format: TextureFormat::R8, + }; unsafe { - gl::GenTextures(1, &mut texture.gl_texture); ck(); + gl::GenTextures(1, &mut texture.gl_texture); + ck(); self.bind_texture(&texture, 0); - gl::TexImage2D(gl::TEXTURE_2D, - 0, - format.gl_internal_format(), - size.x() as GLsizei, - size.y() as GLsizei, - 0, - format.gl_format(), - format.gl_type(), - data_ptr) + gl::TexImage2D( + gl::TEXTURE_2D, + 0, + format.gl_internal_format(), + size.x() as GLsizei, + size.y() as GLsizei, + 0, + format.gl_format(), + format.gl_type(), + data_ptr, + ) } self.set_texture_sampling_mode(&texture, TextureSamplingFlags::empty()); @@ -407,29 +494,39 @@ impl Device for GLDevice { let source = output; let gl_shader_kind = match kind { - ShaderKind::Vertex => gl::VERTEX_SHADER, + ShaderKind::Vertex => gl::VERTEX_SHADER, ShaderKind::Fragment => gl::FRAGMENT_SHADER, - ShaderKind::Compute => gl::COMPUTE_SHADER, + ShaderKind::Compute => gl::COMPUTE_SHADER, }; unsafe { - let gl_shader = gl::CreateShader(gl_shader_kind); ck(); - gl::ShaderSource(gl_shader, - 1, - [source.as_ptr() as *const GLchar].as_ptr(), - [source.len() as GLint].as_ptr()); ck(); - gl::CompileShader(gl_shader); ck(); + let gl_shader = gl::CreateShader(gl_shader_kind); + ck(); + gl::ShaderSource( + gl_shader, + 1, + [source.as_ptr() as *const GLchar].as_ptr(), + [source.len() as GLint].as_ptr(), + ); + ck(); + gl::CompileShader(gl_shader); + ck(); let mut compile_status = 0; - gl::GetShaderiv(gl_shader, gl::COMPILE_STATUS, &mut compile_status); ck(); + gl::GetShaderiv(gl_shader, gl::COMPILE_STATUS, &mut compile_status); + ck(); if compile_status != gl::TRUE as GLint { let mut info_log_length = 0; - gl::GetShaderiv(gl_shader, gl::INFO_LOG_LENGTH, &mut info_log_length); ck(); + gl::GetShaderiv(gl_shader, gl::INFO_LOG_LENGTH, &mut info_log_length); + ck(); let mut info_log = vec![0; info_log_length as usize]; - gl::GetShaderInfoLog(gl_shader, - info_log.len() as GLint, - ptr::null_mut(), - info_log.as_mut_ptr() as *mut GLchar); ck(); + gl::GetShaderInfoLog( + gl_shader, + info_log.len() as GLint, + ptr::null_mut(), + info_log.as_mut_ptr() as *mut GLchar, + ); + ck(); error!("Shader info log:\n{}", String::from_utf8_lossy(&info_log)); panic!("{:?} shader '{}' compilation failed", kind, name); } @@ -438,46 +535,64 @@ impl Device for GLDevice { } } - fn create_program_from_shaders(&self, - _resources: &dyn ResourceLoader, - name: &str, - shaders: ProgramKind) - -> GLProgram { + fn create_program_from_shaders( + &self, + _resources: &dyn ResourceLoader, + name: &str, + shaders: ProgramKind, + ) -> GLProgram { let gl_program; unsafe { - gl_program = gl::CreateProgram(); ck(); + gl_program = gl::CreateProgram(); + ck(); match shaders { ProgramKind::Raster { vertex: ref vertex_shader, fragment: ref fragment_shader, } => { - gl::AttachShader(gl_program, vertex_shader.gl_shader); ck(); - gl::AttachShader(gl_program, fragment_shader.gl_shader); ck(); + gl::AttachShader(gl_program, vertex_shader.gl_shader); + ck(); + gl::AttachShader(gl_program, fragment_shader.gl_shader); + ck(); } ProgramKind::Compute(ref compute_shader) => { - gl::AttachShader(gl_program, compute_shader.gl_shader); ck(); + gl::AttachShader(gl_program, compute_shader.gl_shader); + ck(); } } - gl::LinkProgram(gl_program); ck(); + gl::LinkProgram(gl_program); + ck(); let mut link_status = 0; - gl::GetProgramiv(gl_program, gl::LINK_STATUS, &mut link_status); ck(); + gl::GetProgramiv(gl_program, gl::LINK_STATUS, &mut link_status); + ck(); if link_status != gl::TRUE as GLint { let mut info_log_length = 0; - gl::GetProgramiv(gl_program, gl::INFO_LOG_LENGTH, &mut info_log_length); ck(); + gl::GetProgramiv(gl_program, gl::INFO_LOG_LENGTH, &mut info_log_length); + ck(); let mut info_log = vec![0; info_log_length as usize]; - gl::GetProgramInfoLog(gl_program, - info_log.len() as GLint, - ptr::null_mut(), - info_log.as_mut_ptr() as *mut GLchar); ck(); + gl::GetProgramInfoLog( + gl_program, + info_log.len() as GLint, + ptr::null_mut(), + info_log.as_mut_ptr() as *mut GLchar, + ); + ck(); eprintln!("Program info log:\n{}", String::from_utf8_lossy(&info_log)); panic!("Program '{}' linking failed", name); } } - let parameters = GLProgramParameters { textures: vec![], images: vec![] }; + let parameters = GLProgramParameters { + textures: vec![], + images: vec![], + }; - GLProgram { gl_program, shaders, parameters: RefCell::new(parameters) } + GLProgram { + gl_program, + shaders, + parameters: RefCell::new(parameters), + } } #[inline] @@ -489,28 +604,31 @@ impl Device for GLDevice { fn create_vertex_array(&self) -> GLVertexArray { unsafe { let mut array = GLVertexArray { gl_vertex_array: 0 }; - gl::GenVertexArrays(1, &mut array.gl_vertex_array); ck(); + gl::GenVertexArrays(1, &mut array.gl_vertex_array); + ck(); array } } fn get_vertex_attr(&self, program: &Self::Program, name: &str) -> Option { let name = CString::new(format!("a{}", name)).unwrap(); - let attr = unsafe { - gl::GetAttribLocation(program.gl_program, name.as_ptr() as *const GLchar) - }; ck(); + let attr = + unsafe { gl::GetAttribLocation(program.gl_program, name.as_ptr() as *const GLchar) }; + ck(); if attr < 0 { None } else { - Some(GLVertexAttr { attr: attr as GLuint }) + Some(GLVertexAttr { + attr: attr as GLuint, + }) } } fn get_uniform(&self, program: &GLProgram, name: &str) -> GLUniform { let name = CString::new(format!("u{}", name)).unwrap(); - let location = unsafe { - gl::GetUniformLocation(program.gl_program, name.as_ptr() as *const GLchar) - }; ck(); + let location = + unsafe { gl::GetUniformLocation(program.gl_program, name.as_ptr() as *const GLchar) }; + ck(); GLUniform { location } } @@ -525,7 +643,10 @@ impl Device for GLDevice { index } }; - GLTextureParameter { uniform, texture_unit: index as GLuint } + GLTextureParameter { + uniform, + texture_unit: index as GLuint, + } } fn get_image_parameter(&self, program: &GLProgram, name: &str) -> GLImageParameter { @@ -539,17 +660,24 @@ impl Device for GLDevice { index } }; - GLImageParameter { uniform, image_unit: index as GLuint } + GLImageParameter { + uniform, + image_unit: index as GLuint, + } } fn get_storage_buffer(&self, _: &Self::Program, _: &str, binding: u32) -> GLStorageBuffer { - GLStorageBuffer { location: binding as GLint } + GLStorageBuffer { + location: binding as GLint, + } } - fn configure_vertex_attr(&self, - vertex_array: &GLVertexArray, - attr: &GLVertexAttr, - descriptor: &VertexAttrDescriptor) { + fn configure_vertex_attr( + &self, + vertex_array: &GLVertexArray, + attr: &GLVertexAttr, + descriptor: &VertexAttrDescriptor, + ) { debug_assert_ne!(descriptor.stride, 0); self.bind_vertex_array(vertex_array); @@ -563,24 +691,32 @@ impl Device for GLDevice { } else { gl::FALSE }; - gl::VertexAttribPointer(attr.attr, - descriptor.size as GLint, - attr_type, - normalized, - descriptor.stride as GLint, - descriptor.offset as *const GLvoid); ck(); + gl::VertexAttribPointer( + attr.attr, + descriptor.size as GLint, + attr_type, + normalized, + descriptor.stride as GLint, + descriptor.offset as *const GLvoid, + ); + ck(); } VertexAttrClass::Int => { - gl::VertexAttribIPointer(attr.attr, - descriptor.size as GLint, - attr_type, - descriptor.stride as GLint, - descriptor.offset as *const GLvoid); ck(); + gl::VertexAttribIPointer( + attr.attr, + descriptor.size as GLint, + attr_type, + descriptor.stride as GLint, + descriptor.offset as *const GLvoid, + ); + ck(); } } - gl::VertexAttribDivisor(attr.attr, descriptor.divisor); ck(); - gl::EnableVertexAttribArray(attr.attr); ck(); + gl::VertexAttribDivisor(attr.attr, descriptor.divisor); + ck(); + gl::EnableVertexAttribArray(attr.attr); + ck(); } self.unbind_vertex_array(); @@ -589,24 +725,36 @@ impl Device for GLDevice { fn create_framebuffer(&self, texture: GLTexture) -> GLFramebuffer { let mut gl_framebuffer = 0; unsafe { - gl::GenFramebuffers(1, &mut gl_framebuffer); ck(); - gl::BindFramebuffer(gl::FRAMEBUFFER, gl_framebuffer); ck(); + gl::GenFramebuffers(1, &mut gl_framebuffer); + ck(); + gl::BindFramebuffer(gl::FRAMEBUFFER, gl_framebuffer); + ck(); self.bind_texture(&texture, 0); - gl::FramebufferTexture2D(gl::FRAMEBUFFER, - gl::COLOR_ATTACHMENT0, - gl::TEXTURE_2D, - texture.gl_texture, - 0); ck(); - assert_eq!(gl::CheckFramebufferStatus(gl::FRAMEBUFFER), gl::FRAMEBUFFER_COMPLETE); + gl::FramebufferTexture2D( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + gl::TEXTURE_2D, + texture.gl_texture, + 0, + ); + ck(); + assert_eq!( + gl::CheckFramebufferStatus(gl::FRAMEBUFFER), + gl::FRAMEBUFFER_COMPLETE + ); } - GLFramebuffer { gl_framebuffer, texture } + GLFramebuffer { + gl_framebuffer, + texture, + } } fn create_buffer(&self, mode: BufferUploadMode) -> GLBuffer { unsafe { let mut gl_buffer = 0; - gl::GenBuffers(1, &mut gl_buffer); ck(); + gl::GenBuffers(1, &mut gl_buffer); + ck(); let object = Rc::new(GLBufferObject { gl_buffer }); GLBuffer { object, mode } } @@ -621,24 +769,32 @@ impl Device for GLDevice { let len = (len * mem::size_of::()) as GLsizeiptr; let usage = buffer.mode.to_gl_usage(); unsafe { - gl::BindBuffer(target, buffer.object.gl_buffer); ck(); - gl::BufferData(target, len, ptr, usage); ck(); + gl::BindBuffer(target, buffer.object.gl_buffer); + ck(); + gl::BufferData(target, len, ptr, usage); + ck(); } } - fn upload_to_buffer(&self, - buffer: &Self::Buffer, - position: usize, - data: &[T], - target: BufferTarget) { + fn upload_to_buffer( + &self, + buffer: &Self::Buffer, + position: usize, + data: &[T], + target: BufferTarget, + ) { let target = target.to_gl_target(); let len = (data.len() * mem::size_of::()) as GLsizeiptr; unsafe { - gl::BindBuffer(target, buffer.object.gl_buffer); ck(); - gl::BufferSubData(target, - position as GLintptr, - len, - data.as_ptr() as *const GLvoid); ck(); + gl::BindBuffer(target, buffer.object.gl_buffer); + ck(); + gl::BufferSubData( + target, + position as GLintptr, + len, + data.as_ptr() as *const GLvoid, + ); + ck(); } } @@ -655,7 +811,8 @@ impl Device for GLDevice { format: framebuffer.texture.format, }; unsafe { - gl::DeleteFramebuffers(1, &mut framebuffer.gl_framebuffer); ck(); + gl::DeleteFramebuffers(1, &mut framebuffer.gl_framebuffer); + ck(); } mem::forget(framebuffer); texture @@ -674,34 +831,46 @@ impl Device for GLDevice { fn set_texture_sampling_mode(&self, texture: &Self::Texture, flags: TextureSamplingFlags) { self.bind_texture(texture, 0); unsafe { - gl::TexParameteri(gl::TEXTURE_2D, - gl::TEXTURE_MIN_FILTER, - if flags.contains(TextureSamplingFlags::NEAREST_MIN) { - gl::NEAREST as GLint - } else { - gl::LINEAR as GLint - }); ck(); - gl::TexParameteri(gl::TEXTURE_2D, - gl::TEXTURE_MAG_FILTER, - if flags.contains(TextureSamplingFlags::NEAREST_MAG) { - gl::NEAREST as GLint - } else { - gl::LINEAR as GLint - }); ck(); - gl::TexParameteri(gl::TEXTURE_2D, - gl::TEXTURE_WRAP_S, - if flags.contains(TextureSamplingFlags::REPEAT_U) { - gl::REPEAT as GLint - } else { - gl::CLAMP_TO_EDGE as GLint - }); ck(); - gl::TexParameteri(gl::TEXTURE_2D, - gl::TEXTURE_WRAP_T, - if flags.contains(TextureSamplingFlags::REPEAT_V) { - gl::REPEAT as GLint - } else { - gl::CLAMP_TO_EDGE as GLint - }); ck(); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_MIN_FILTER, + if flags.contains(TextureSamplingFlags::NEAREST_MIN) { + gl::NEAREST as GLint + } else { + gl::LINEAR as GLint + }, + ); + ck(); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_MAG_FILTER, + if flags.contains(TextureSamplingFlags::NEAREST_MAG) { + gl::NEAREST as GLint + } else { + gl::LINEAR as GLint + }, + ); + ck(); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_S, + if flags.contains(TextureSamplingFlags::REPEAT_U) { + gl::REPEAT as GLint + } else { + gl::CLAMP_TO_EDGE as GLint + }, + ); + ck(); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_T, + if flags.contains(TextureSamplingFlags::REPEAT_V) { + gl::REPEAT as GLint + } else { + gl::CLAMP_TO_EDGE as GLint + }, + ); + ck(); } } @@ -716,33 +885,42 @@ impl Device for GLDevice { unsafe { self.bind_texture(texture, 0); if rect.origin() == Vector2I::default() && rect.size() == texture.size { - gl::TexImage2D(gl::TEXTURE_2D, - 0, - texture.format.gl_internal_format(), - texture.size.x() as GLsizei, - texture.size.y() as GLsizei, - 0, - texture.format.gl_format(), - texture.format.gl_type(), - data_ptr); ck(); + gl::TexImage2D( + gl::TEXTURE_2D, + 0, + texture.format.gl_internal_format(), + texture.size.x() as GLsizei, + texture.size.y() as GLsizei, + 0, + texture.format.gl_format(), + texture.format.gl_type(), + data_ptr, + ); + ck(); } else { - gl::TexSubImage2D(gl::TEXTURE_2D, - 0, - rect.origin().x(), - rect.origin().y(), - rect.size().x() as GLsizei, - rect.size().y() as GLsizei, - texture.format.gl_format(), - texture.format.gl_type(), - data_ptr); ck(); + gl::TexSubImage2D( + gl::TEXTURE_2D, + 0, + rect.origin().x(), + rect.origin().y(), + rect.size().x() as GLsizei, + rect.size().y() as GLsizei, + texture.format.gl_format(), + texture.format.gl_type(), + data_ptr, + ); + ck(); } } self.set_texture_sampling_mode(texture, TextureSamplingFlags::empty()); } - fn read_pixels(&self, render_target: &RenderTarget, viewport: RectI) - -> GLTextureDataReceiver { + fn read_pixels( + &self, + render_target: &RenderTarget, + viewport: RectI, + ) -> GLTextureDataReceiver { let (origin, size) = (viewport.origin(), viewport.size()); let format = self.render_target_format(render_target); self.bind_render_target(render_target); @@ -750,32 +928,54 @@ impl Device for GLDevice { unsafe { let mut gl_pixel_buffer = 0; - gl::GenBuffers(1, &mut gl_pixel_buffer); ck(); - gl::BindBuffer(gl::PIXEL_PACK_BUFFER, gl_pixel_buffer); ck(); - gl::BufferData(gl::PIXEL_PACK_BUFFER, - byte_size as GLsizeiptr, - ptr::null(), - gl::STATIC_READ); ck(); + gl::GenBuffers(1, &mut gl_pixel_buffer); + ck(); + gl::BindBuffer(gl::PIXEL_PACK_BUFFER, gl_pixel_buffer); + ck(); + gl::BufferData( + gl::PIXEL_PACK_BUFFER, + byte_size as GLsizeiptr, + ptr::null(), + gl::STATIC_READ, + ); + ck(); - gl::ReadPixels(origin.x(), - origin.y(), - size.x() as GLsizei, - size.y() as GLsizei, - format.gl_format(), - format.gl_type(), - 0 as *mut GLvoid); ck(); + gl::ReadPixels( + origin.x(), + origin.y(), + size.x() as GLsizei, + size.y() as GLsizei, + format.gl_format(), + format.gl_type(), + 0 as *mut GLvoid, + ); + ck(); let gl_sync = gl::FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0); - GLTextureDataReceiver { gl_pixel_buffer, gl_sync, size, format } + GLTextureDataReceiver { + gl_pixel_buffer, + gl_sync, + size, + format, + } } } - fn read_buffer(&self, buffer: &GLBuffer, target: BufferTarget, range: Range) - -> GLBufferDataReceiver { + fn read_buffer( + &self, + buffer: &GLBuffer, + target: BufferTarget, + range: Range, + ) -> GLBufferDataReceiver { unsafe { let gl_sync = gl::FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0); - GLBufferDataReceiver { object: buffer.object.clone(), gl_sync, range, target } + GLBufferDataReceiver { + object: buffer.object.clone(), + gl_sync, + range, + target, + } } } @@ -791,9 +991,12 @@ impl Device for GLDevice { fn draw_arrays(&self, index_count: u32, render_state: &RenderState) { self.set_render_state(render_state); unsafe { - gl::DrawArrays(render_state.primitive.to_gl_primitive(), - 0, - index_count as GLsizei); ck(); + gl::DrawArrays( + render_state.primitive.to_gl_primitive(), + 0, + index_count as GLsizei, + ); + ck(); } self.reset_render_state(render_state); } @@ -801,25 +1004,33 @@ impl Device for GLDevice { fn draw_elements(&self, index_count: u32, render_state: &RenderState) { self.set_render_state(render_state); unsafe { - gl::DrawElements(render_state.primitive.to_gl_primitive(), - index_count as GLsizei, - gl::UNSIGNED_INT, - ptr::null()); ck(); + gl::DrawElements( + render_state.primitive.to_gl_primitive(), + index_count as GLsizei, + gl::UNSIGNED_INT, + ptr::null(), + ); + ck(); } self.reset_render_state(render_state); } - fn draw_elements_instanced(&self, - index_count: u32, - instance_count: u32, - render_state: &RenderState) { + fn draw_elements_instanced( + &self, + index_count: u32, + instance_count: u32, + render_state: &RenderState, + ) { self.set_render_state(render_state); unsafe { - gl::DrawElementsInstanced(render_state.primitive.to_gl_primitive(), - index_count as GLsizei, - gl::UNSIGNED_INT, - ptr::null(), - instance_count as GLsizei); ck(); + gl::DrawElementsInstanced( + render_state.primitive.to_gl_primitive(), + index_count as GLsizei, + gl::UNSIGNED_INT, + ptr::null(), + instance_count as GLsizei, + ); + ck(); } self.reset_render_state(render_state); } @@ -827,7 +1038,8 @@ impl Device for GLDevice { fn dispatch_compute(&self, dimensions: ComputeDimensions, compute_state: &ComputeState) { self.set_compute_state(compute_state); unsafe { - gl::DispatchCompute(dimensions.x, dimensions.y, dimensions.z); ck(); + gl::DispatchCompute(dimensions.x, dimensions.y, dimensions.z); + ck(); } self.reset_compute_state(compute_state); } @@ -836,7 +1048,8 @@ impl Device for GLDevice { fn create_timer_query(&self) -> GLTimerQuery { let mut query = GLTimerQuery { gl_query: 0 }; unsafe { - gl::GenQueries(1, &mut query.gl_query); ck(); + gl::GenQueries(1, &mut query.gl_query); + ck(); } query } @@ -844,21 +1057,24 @@ impl Device for GLDevice { #[inline] fn begin_timer_query(&self, query: &Self::TimerQuery) { unsafe { - gl::BeginQuery(gl::TIME_ELAPSED, query.gl_query); ck(); + gl::BeginQuery(gl::TIME_ELAPSED, query.gl_query); + ck(); } } #[inline] fn end_timer_query(&self, _: &Self::TimerQuery) { unsafe { - gl::EndQuery(gl::TIME_ELAPSED); ck(); + gl::EndQuery(gl::TIME_ELAPSED); + ck(); } } fn try_recv_timer_query(&self, query: &Self::TimerQuery) -> Option { unsafe { let mut result = 0; - gl::GetQueryObjectiv(query.gl_query, gl::QUERY_RESULT_AVAILABLE, &mut result); ck(); + gl::GetQueryObjectiv(query.gl_query, gl::QUERY_RESULT_AVAILABLE, &mut result); + ck(); if result == gl::FALSE as GLint { None } else { @@ -870,16 +1086,16 @@ impl Device for GLDevice { fn recv_timer_query(&self, query: &Self::TimerQuery) -> Duration { unsafe { let mut result = 0; - gl::GetQueryObjectui64v(query.gl_query, gl::QUERY_RESULT, &mut result); ck(); + gl::GetQueryObjectui64v(query.gl_query, gl::QUERY_RESULT, &mut result); + ck(); Duration::from_nanos(result) } } fn try_recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> Option { unsafe { - let result = gl::ClientWaitSync(receiver.gl_sync, - gl::SYNC_FLUSH_COMMANDS_BIT, - 0); ck(); + let result = gl::ClientWaitSync(receiver.gl_sync, gl::SYNC_FLUSH_COMMANDS_BIT, 0); + ck(); if result == gl::TIMEOUT_EXPIRED || result == gl::WAIT_FAILED { None } else { @@ -890,9 +1106,8 @@ impl Device for GLDevice { fn recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> TextureData { unsafe { - let result = gl::ClientWaitSync(receiver.gl_sync, - gl::SYNC_FLUSH_COMMANDS_BIT, - !0); ck(); + let result = gl::ClientWaitSync(receiver.gl_sync, gl::SYNC_FLUSH_COMMANDS_BIT, !0); + ck(); debug_assert!(result != gl::TIMEOUT_EXPIRED && result != gl::WAIT_FAILED); self.get_texture_data(receiver) } @@ -900,9 +1115,8 @@ impl Device for GLDevice { fn try_recv_buffer(&self, receiver: &Self::BufferDataReceiver) -> Option> { unsafe { - let result = gl::ClientWaitSync(receiver.gl_sync, - gl::SYNC_FLUSH_COMMANDS_BIT, - 0); ck(); + let result = gl::ClientWaitSync(receiver.gl_sync, gl::SYNC_FLUSH_COMMANDS_BIT, 0); + ck(); if result == gl::TIMEOUT_EXPIRED || result == gl::WAIT_FAILED { None } else { @@ -913,9 +1127,8 @@ impl Device for GLDevice { fn recv_buffer(&self, receiver: &Self::BufferDataReceiver) -> Vec { unsafe { - let result = gl::ClientWaitSync(receiver.gl_sync, - gl::SYNC_FLUSH_COMMANDS_BIT, - !0); ck(); + let result = gl::ClientWaitSync(receiver.gl_sync, gl::SYNC_FLUSH_COMMANDS_BIT, !0); + ck(); debug_assert!(result != gl::TIMEOUT_EXPIRED && result != gl::WAIT_FAILED); self.get_buffer_data(receiver) } @@ -925,23 +1138,28 @@ impl Device for GLDevice { fn bind_buffer(&self, vertex_array: &GLVertexArray, buffer: &GLBuffer, target: BufferTarget) { self.bind_vertex_array(vertex_array); unsafe { - gl::BindBuffer(target.to_gl_target(), buffer.object.gl_buffer); ck(); + gl::BindBuffer(target.to_gl_target(), buffer.object.gl_buffer); + ck(); } self.unbind_vertex_array(); } #[inline] - fn create_shader(&self, resources: &dyn ResourceLoader, name: &str, kind: ShaderKind) - -> Self::Shader { + fn create_shader( + &self, + resources: &dyn ResourceLoader, + name: &str, + kind: ShaderKind, + ) -> Self::Shader { match (self.version, kind) { (GLVersion::GL3, ShaderKind::Compute) | (GLVersion::GLES3, ShaderKind::Compute) => { panic!("Compute shaders are not supported on OpenGL versions prior to 4!") } - (GLVersion::GL3, ShaderKind::Vertex) | - (GLVersion::GL3, ShaderKind::Fragment) | - (GLVersion::GLES3, ShaderKind::Vertex) | - (GLVersion::GLES3, ShaderKind::Fragment) | - (GLVersion::GL4, _) => {} + (GLVersion::GL3, ShaderKind::Vertex) + | (GLVersion::GL3, ShaderKind::Fragment) + | (GLVersion::GLES3, ShaderKind::Vertex) + | (GLVersion::GLES3, ShaderKind::Fragment) + | (GLVersion::GL4, _) => {} } let directory = match self.version { GLVersion::GL3 | GLVersion::GLES3 => "gl3", @@ -958,14 +1176,16 @@ impl Device for GLDevice { fn add_fence(&self) -> Self::Fence { unsafe { - let gl_sync = gl::FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0); ck(); + let gl_sync = gl::FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0); + ck(); GLFence { gl_sync } } } fn wait_for_fence(&self, fence: &Self::Fence) { unsafe { - gl::ClientWaitSync(fence.gl_sync, gl::SYNC_FLUSH_COMMANDS_BIT, 0); ck(); + gl::ClientWaitSync(fence.gl_sync, gl::SYNC_FLUSH_COMMANDS_BIT, 0); + ck(); } } } @@ -980,69 +1200,83 @@ impl GLDevice { fn bind_vertex_array(&self, vertex_array: &GLVertexArray) { unsafe { - gl::BindVertexArray(vertex_array.gl_vertex_array); ck(); + gl::BindVertexArray(vertex_array.gl_vertex_array); + ck(); } } fn unbind_vertex_array(&self) { unsafe { - gl::BindVertexArray(0); ck(); + gl::BindVertexArray(0); + ck(); } } fn bind_texture(&self, texture: &GLTexture, unit: u32) { unsafe { - gl::ActiveTexture(gl::TEXTURE0 + unit); ck(); - gl::BindTexture(gl::TEXTURE_2D, texture.gl_texture); ck(); + gl::ActiveTexture(gl::TEXTURE0 + unit); + ck(); + gl::BindTexture(gl::TEXTURE_2D, texture.gl_texture); + ck(); } } fn unbind_texture(&self, unit: u32) { unsafe { - gl::ActiveTexture(gl::TEXTURE0 + unit); ck(); - gl::BindTexture(gl::TEXTURE_2D, 0); ck(); + gl::ActiveTexture(gl::TEXTURE0 + unit); + ck(); + gl::BindTexture(gl::TEXTURE_2D, 0); + ck(); } } fn bind_image(&self, binding: &ImageBinding) { unsafe { - gl::BindImageTexture(binding.0.image_unit, - binding.1.gl_texture, - 0, - gl::FALSE, - 0, - binding.2.to_gl_access(), - binding.1.format.gl_internal_format() as GLenum); ck(); + gl::BindImageTexture( + binding.0.image_unit, + binding.1.gl_texture, + 0, + gl::FALSE, + 0, + binding.2.to_gl_access(), + binding.1.format.gl_internal_format() as GLenum, + ); + ck(); } } fn unbind_image(&self, unit: u32) { unsafe { - gl::BindImageTexture(unit, 0, 0, gl::FALSE, 0, gl::READ_ONLY, gl::RGBA8); ck(); + gl::BindImageTexture(unit, 0, 0, gl::FALSE, 0, gl::READ_ONLY, gl::RGBA8); + ck(); } } fn use_program(&self, program: &GLProgram) { unsafe { - gl::UseProgram(program.gl_program); ck(); + gl::UseProgram(program.gl_program); + ck(); } } fn unuse_program(&self) { unsafe { - gl::UseProgram(0); ck(); + gl::UseProgram(0); + ck(); } } fn bind_default_framebuffer(&self) { unsafe { - gl::BindFramebuffer(gl::FRAMEBUFFER, self.default_framebuffer); ck(); + gl::BindFramebuffer(gl::FRAMEBUFFER, self.default_framebuffer); + ck(); } } fn bind_framebuffer(&self, framebuffer: &GLFramebuffer) { unsafe { - gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.gl_framebuffer); ck(); + gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.gl_framebuffer); + ck(); } } @@ -1050,9 +1284,11 @@ impl GLDevice { let mut index = 0; while index < source.len() { if source[index..].starts_with(b"{{") { - let end_index = source[index..].iter() - .position(|character| *character == b'}') - .expect("Expected `}`!") + index; + let end_index = source[index..] + .iter() + .position(|character| *character == b'}') + .expect("Expected `}`!") + + index; assert_eq!(source[end_index + 1], b'}'); let ident = String::from_utf8_lossy(&source[(index + 2)..end_index]); if ident == "version" { @@ -1072,22 +1308,29 @@ impl GLDevice { unsafe { let mut flags = 0; if let Some(color) = ops.color { - gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); ck(); - gl::ClearColor(color.r(), color.g(), color.b(), color.a()); ck(); + gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); + ck(); + gl::ClearColor(color.r(), color.g(), color.b(), color.a()); + ck(); flags |= gl::COLOR_BUFFER_BIT; } if let Some(depth) = ops.depth { - gl::DepthMask(gl::TRUE); ck(); - gl::ClearDepthf(depth as _); ck(); // FIXME(pcwalton): GLES + gl::DepthMask(gl::TRUE); + ck(); + gl::ClearDepthf(depth as _); + ck(); // FIXME(pcwalton): GLES flags |= gl::DEPTH_BUFFER_BIT; } if let Some(stencil) = ops.stencil { - gl::StencilMask(!0); ck(); - gl::ClearStencil(stencil as GLint); ck(); + gl::StencilMask(!0); + ck(); + gl::ClearStencil(stencil as GLint); + ck(); flags |= gl::STENCIL_BUFFER_BIT; } if flags != 0 { - gl::Clear(flags); ck(); + gl::Clear(flags); + ck(); } } } @@ -1129,15 +1372,20 @@ impl GLDevice { } } - gl::BindBuffer(gl::PIXEL_PACK_BUFFER, receiver.gl_pixel_buffer); ck(); - gl::GetBufferSubData(gl::PIXEL_PACK_BUFFER, - 0, - texture_data_len as GLsizeiptr, - texture_data_ptr as *mut GLvoid); ck(); - gl::BindBuffer(gl::PIXEL_PACK_BUFFER, 0); ck(); + gl::BindBuffer(gl::PIXEL_PACK_BUFFER, receiver.gl_pixel_buffer); + ck(); + gl::GetBufferSubData( + gl::PIXEL_PACK_BUFFER, + 0, + texture_data_len as GLsizeiptr, + texture_data_ptr as *mut GLvoid, + ); + ck(); + gl::BindBuffer(gl::PIXEL_PACK_BUFFER, 0); + ck(); match texture_data { - TextureData::U8(ref mut pixels) => flip_y(pixels, size, channels), + TextureData::U8(ref mut pixels) => flip_y(pixels, size, channels), TextureData::U16(ref mut pixels) => flip_y(pixels, size, channels), TextureData::F16(ref mut pixels) => flip_y(pixels, size, channels), TextureData::F32(ref mut pixels) => flip_y(pixels, size, channels), @@ -1151,11 +1399,15 @@ impl GLDevice { let mut dest = vec![0; receiver.range.end - receiver.range.start]; let gl_target = receiver.target.to_gl_target(); unsafe { - gl::BindBuffer(gl_target, receiver.object.gl_buffer); ck(); - gl::GetBufferSubData(gl_target, - receiver.range.start as GLintptr, - (receiver.range.end - receiver.range.start) as GLsizeiptr, - dest.as_mut_ptr() as *mut GLvoid); ck(); + gl::BindBuffer(gl_target, receiver.object.gl_buffer); + ck(); + gl::GetBufferSubData( + gl_target, + receiver.range.start as GLintptr, + (receiver.range.end - receiver.range.start) as GLsizeiptr, + dest.as_mut_ptr() as *mut GLvoid, + ); + ck(); } dest } @@ -1169,7 +1421,8 @@ impl Drop for GLVertexArray { #[inline] fn drop(&mut self) { unsafe { - gl::DeleteVertexArrays(1, &mut self.gl_vertex_array); ck(); + gl::DeleteVertexArrays(1, &mut self.gl_vertex_array); + ck(); } } } @@ -1179,39 +1432,47 @@ pub struct GLVertexAttr { } impl GLVertexAttr { - pub fn configure_float(&self, - size: GLint, - gl_type: GLuint, - normalized: bool, - stride: GLsizei, - offset: usize, - divisor: GLuint) { + pub fn configure_float( + &self, + size: GLint, + gl_type: GLuint, + normalized: bool, + stride: GLsizei, + offset: usize, + divisor: GLuint, + ) { unsafe { - gl::VertexAttribPointer(self.attr, - size, - gl_type, - if normalized { gl::TRUE } else { gl::FALSE }, - stride, - offset as *const GLvoid); ck(); - gl::VertexAttribDivisor(self.attr, divisor); ck(); - gl::EnableVertexAttribArray(self.attr); ck(); + gl::VertexAttribPointer( + self.attr, + size, + gl_type, + if normalized { gl::TRUE } else { gl::FALSE }, + stride, + offset as *const GLvoid, + ); + ck(); + gl::VertexAttribDivisor(self.attr, divisor); + ck(); + gl::EnableVertexAttribArray(self.attr); + ck(); } } - pub fn configure_int(&self, - size: GLint, - gl_type: GLuint, - stride: GLsizei, - offset: usize, - divisor: GLuint) { + pub fn configure_int( + &self, + size: GLint, + gl_type: GLuint, + stride: GLsizei, + offset: usize, + divisor: GLuint, + ) { unsafe { - gl::VertexAttribIPointer(self.attr, - size, - gl_type, - stride, - offset as *const GLvoid); ck(); - gl::VertexAttribDivisor(self.attr, divisor); ck(); - gl::EnableVertexAttribArray(self.attr); ck(); + gl::VertexAttribIPointer(self.attr, size, gl_type, stride, offset as *const GLvoid); + ck(); + gl::VertexAttribDivisor(self.attr, divisor); + ck(); + gl::EnableVertexAttribArray(self.attr); + ck(); } } } @@ -1223,7 +1484,8 @@ pub struct GLFence { impl Drop for GLFence { fn drop(&mut self) { unsafe { - gl::DeleteSync(self.gl_sync); ck(); + gl::DeleteSync(self.gl_sync); + ck(); } } } @@ -1236,7 +1498,8 @@ pub struct GLFramebuffer { impl Drop for GLFramebuffer { fn drop(&mut self) { unsafe { - gl::DeleteFramebuffers(1, &mut self.gl_framebuffer); ck(); + gl::DeleteFramebuffers(1, &mut self.gl_framebuffer); + ck(); } } } @@ -1253,7 +1516,8 @@ pub struct GLBufferObject { impl Drop for GLBufferObject { fn drop(&mut self) { unsafe { - gl::DeleteBuffers(1, &mut self.gl_buffer); ck(); + gl::DeleteBuffers(1, &mut self.gl_buffer); + ck(); } } } @@ -1290,7 +1554,8 @@ pub struct GLProgram { impl Drop for GLProgram { fn drop(&mut self) { unsafe { - gl::DeleteProgram(self.gl_program); ck(); + gl::DeleteProgram(self.gl_program); + ck(); } } } @@ -1309,7 +1574,8 @@ pub struct GLShader { impl Drop for GLShader { fn drop(&mut self) { unsafe { - gl::DeleteShader(self.gl_shader); ck(); + gl::DeleteShader(self.gl_shader); + ck(); } } } @@ -1323,7 +1589,8 @@ pub struct GLTexture { impl Drop for GLTexture { fn drop(&mut self) { unsafe { - gl::DeleteTextures(1, &mut self.gl_texture); ck(); + gl::DeleteTextures(1, &mut self.gl_texture); + ck(); } } } @@ -1336,7 +1603,8 @@ impl Drop for GLTimerQuery { #[inline] fn drop(&mut self) { unsafe { - gl::DeleteQueries(1, &mut self.gl_query); ck(); + gl::DeleteQueries(1, &mut self.gl_query); + ck(); } } } @@ -1498,10 +1766,10 @@ impl VertexAttrTypeExt for VertexAttrType { fn to_gl_type(self) -> GLuint { match self { VertexAttrType::F32 => gl::FLOAT, - VertexAttrType::I8 => gl::BYTE, + VertexAttrType::I8 => gl::BYTE, VertexAttrType::I16 => gl::SHORT, VertexAttrType::I32 => gl::INT, - VertexAttrType::U8 => gl::UNSIGNED_BYTE, + VertexAttrType::U8 => gl::UNSIGNED_BYTE, VertexAttrType::U16 => gl::UNSIGNED_SHORT, } } @@ -1532,8 +1800,10 @@ pub struct GLTextureDataReceiver { impl Drop for GLTextureDataReceiver { fn drop(&mut self) { unsafe { - gl::DeleteBuffers(1, &mut self.gl_pixel_buffer); ck(); - gl::DeleteSync(self.gl_sync); ck(); + gl::DeleteBuffers(1, &mut self.gl_pixel_buffer); + ck(); + gl::DeleteSync(self.gl_sync); + ck(); } } } @@ -1569,16 +1839,20 @@ fn ck() { // returns gl::NO_ERROR, but for now we'll just report the first one we find. let err = gl::GetError(); if err != gl::NO_ERROR { - panic!("GL error: 0x{:x} ({})", err, match err { - gl::INVALID_ENUM => "INVALID_ENUM", - gl::INVALID_VALUE => "INVALID_VALUE", - gl::INVALID_OPERATION => "INVALID_OPERATION", - gl::INVALID_FRAMEBUFFER_OPERATION => "INVALID_FRAMEBUFFER_OPERATION", - gl::OUT_OF_MEMORY => "OUT_OF_MEMORY", - gl::STACK_UNDERFLOW => "STACK_UNDERFLOW", - gl::STACK_OVERFLOW => "STACK_OVERFLOW", - _ => "Unknown" - }); + panic!( + "GL error: 0x{:x} ({})", + err, + match err { + gl::INVALID_ENUM => "INVALID_ENUM", + gl::INVALID_VALUE => "INVALID_VALUE", + gl::INVALID_OPERATION => "INVALID_OPERATION", + gl::INVALID_FRAMEBUFFER_OPERATION => "INVALID_FRAMEBUFFER_OPERATION", + gl::OUT_OF_MEMORY => "OUT_OF_MEMORY", + gl::STACK_UNDERFLOW => "STACK_UNDERFLOW", + gl::STACK_OVERFLOW => "STACK_OVERFLOW", + _ => "Unknown", + } + ); } } } diff --git a/gpu/src/allocator.rs b/gpu/src/allocator.rs index 0e8ec203..b393a0c1 100644 --- a/gpu/src/allocator.rs +++ b/gpu/src/allocator.rs @@ -11,8 +11,8 @@ //! GPU memory management. use crate::{BufferData, BufferTarget, BufferUploadMode, Device, TextureFormat}; -use instant::Instant; use fxhash::FxHashMap; +use instant::Instant; use pathfinder_geometry::vector::Vector2I; use std::collections::VecDeque; use std::default::Default; @@ -31,7 +31,10 @@ const DECAY_TIME: f32 = 0.250; // This helps avoid stalls. This is admittedly a bit of a hack. const REUSE_TIME: f32 = 0.015; -pub struct GPUMemoryAllocator where D: Device { +pub struct GPUMemoryAllocator +where + D: Device, +{ general_buffers_in_use: FxHashMap>, index_buffers_in_use: FxHashMap>, textures_in_use: FxHashMap>, @@ -45,34 +48,61 @@ pub struct GPUMemoryAllocator where D: Device { bytes_allocated: u64, } -struct BufferAllocation where D: Device { +struct BufferAllocation +where + D: Device, +{ buffer: D::Buffer, size: u64, tag: BufferTag, } -struct TextureAllocation where D: Device { +struct TextureAllocation +where + D: Device, +{ texture: D::Texture, descriptor: TextureDescriptor, tag: TextureTag, } -struct FramebufferAllocation where D: Device { +struct FramebufferAllocation +where + D: Device, +{ framebuffer: D::Framebuffer, descriptor: TextureDescriptor, tag: FramebufferTag, } -struct FreeObject where D: Device { +struct FreeObject +where + D: Device, +{ timestamp: Instant, kind: FreeObjectKind, } -enum FreeObjectKind where D: Device { - GeneralBuffer { id: GeneralBufferID, allocation: BufferAllocation }, - IndexBuffer { id: IndexBufferID, allocation: BufferAllocation }, - Texture { id: TextureID, allocation: TextureAllocation }, - Framebuffer { id: FramebufferID, allocation: FramebufferAllocation }, +enum FreeObjectKind +where + D: Device, +{ + GeneralBuffer { + id: GeneralBufferID, + allocation: BufferAllocation, + }, + IndexBuffer { + id: IndexBufferID, + allocation: BufferAllocation, + }, + Texture { + id: TextureID, + allocation: TextureAllocation, + }, + Framebuffer { + id: FramebufferID, + allocation: FramebufferAllocation, + }, } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -108,7 +138,10 @@ pub struct TextureTag(pub &'static str); #[derive(Clone, Copy, Debug, PartialEq)] pub struct FramebufferTag(pub &'static str); -impl GPUMemoryAllocator where D: Device { +impl GPUMemoryAllocator +where + D: Device, +{ pub fn new() -> GPUMemoryAllocator { GPUMemoryAllocator { general_buffers_in_use: FxHashMap::default(), @@ -125,8 +158,12 @@ impl GPUMemoryAllocator where D: Device { } } - pub fn allocate_general_buffer(&mut self, device: &D, size: u64, tag: BufferTag) - -> GeneralBufferID { + pub fn allocate_general_buffer( + &mut self, + device: &D, + size: u64, + tag: BufferTag, + ) -> GeneralBufferID { let mut byte_size = size * mem::size_of::() as u64; if byte_size < MAX_BUFFER_SIZE_CLASS { byte_size = byte_size.next_power_of_two(); @@ -139,8 +176,8 @@ impl GPUMemoryAllocator where D: Device { FreeObject { ref timestamp, kind: FreeObjectKind::GeneralBuffer { ref allocation, .. }, - } if allocation.size == byte_size && - (now - *timestamp).as_secs_f32() >= REUSE_TIME => {} + } if allocation.size == byte_size + && (now - *timestamp).as_secs_f32() >= REUSE_TIME => {} _ => continue, } @@ -148,9 +185,7 @@ impl GPUMemoryAllocator where D: Device { Some(FreeObject { kind: FreeObjectKind::GeneralBuffer { id, allocation }, .. - }) => { - (id, allocation) - } + }) => (id, allocation), _ => unreachable!(), }; @@ -161,29 +196,44 @@ impl GPUMemoryAllocator where D: Device { } let buffer = device.create_buffer(BufferUploadMode::Dynamic); - device.allocate_buffer::(&buffer, - BufferData::Uninitialized(byte_size as usize), - BufferTarget::Vertex); + device.allocate_buffer::( + &buffer, + BufferData::Uninitialized(byte_size as usize), + BufferTarget::Vertex, + ); let id = self.next_general_buffer_id; self.next_general_buffer_id.0 += 1; - debug!("mapping general buffer: {:?} {} ({}x{}) {:?}", - id, - byte_size, - size, - mem::size_of::(), - tag); + debug!( + "mapping general buffer: {:?} {} ({}x{}) {:?}", + id, + byte_size, + size, + mem::size_of::(), + tag + ); - self.general_buffers_in_use.insert(id, BufferAllocation { buffer, size: byte_size, tag }); + self.general_buffers_in_use.insert( + id, + BufferAllocation { + buffer, + size: byte_size, + tag, + }, + ); self.bytes_allocated += byte_size; self.bytes_committed += byte_size; id } - pub fn allocate_index_buffer(&mut self, device: &D, size: u64, tag: BufferTag) - -> IndexBufferID { + pub fn allocate_index_buffer( + &mut self, + device: &D, + size: u64, + tag: BufferTag, + ) -> IndexBufferID { let mut byte_size = size * mem::size_of::() as u64; if byte_size < MAX_BUFFER_SIZE_CLASS { byte_size = byte_size.next_power_of_two(); @@ -196,15 +246,16 @@ impl GPUMemoryAllocator where D: Device { FreeObject { ref timestamp, kind: FreeObjectKind::IndexBuffer { ref allocation, .. }, - } if allocation.size == byte_size && - (now - *timestamp).as_secs_f32() >= REUSE_TIME => {} + } if allocation.size == byte_size + && (now - *timestamp).as_secs_f32() >= REUSE_TIME => {} _ => continue, } let (id, mut allocation) = match self.free_objects.remove(free_object_index) { - Some(FreeObject { kind: FreeObjectKind::IndexBuffer { id, allocation }, .. }) => { - (id, allocation) - } + Some(FreeObject { + kind: FreeObjectKind::IndexBuffer { id, allocation }, + .. + }) => (id, allocation), _ => unreachable!(), }; @@ -215,33 +266,45 @@ impl GPUMemoryAllocator where D: Device { } let buffer = device.create_buffer(BufferUploadMode::Dynamic); - device.allocate_buffer::(&buffer, - BufferData::Uninitialized(byte_size as usize), - BufferTarget::Index); + device.allocate_buffer::( + &buffer, + BufferData::Uninitialized(byte_size as usize), + BufferTarget::Index, + ); let id = self.next_index_buffer_id; self.next_index_buffer_id.0 += 1; - debug!("mapping index buffer: {:?} {} ({}x{}) {:?}", - id, - byte_size, - size, - mem::size_of::(), - tag); + debug!( + "mapping index buffer: {:?} {} ({}x{}) {:?}", + id, + byte_size, + size, + mem::size_of::(), + tag + ); - self.index_buffers_in_use.insert(id, BufferAllocation { buffer, size: byte_size, tag }); + self.index_buffers_in_use.insert( + id, + BufferAllocation { + buffer, + size: byte_size, + tag, + }, + ); self.bytes_allocated += byte_size; self.bytes_committed += byte_size; id } - pub fn allocate_texture(&mut self, - device: &D, - size: Vector2I, - format: TextureFormat, - tag: TextureTag) - -> TextureID { + pub fn allocate_texture( + &mut self, + device: &D, + size: Vector2I, + format: TextureFormat, + tag: TextureTag, + ) -> TextureID { let descriptor = TextureDescriptor { width: size.x() as u32, height: size.y() as u32, @@ -251,15 +314,18 @@ impl GPUMemoryAllocator where D: Device { for free_object_index in 0..self.free_objects.len() { match self.free_objects[free_object_index] { - FreeObject { kind: FreeObjectKind::Texture { ref allocation, .. }, .. } if - allocation.descriptor == descriptor => {} + FreeObject { + kind: FreeObjectKind::Texture { ref allocation, .. }, + .. + } if allocation.descriptor == descriptor => {} _ => continue, } let (id, mut allocation) = match self.free_objects.remove(free_object_index) { - Some(FreeObject { kind: FreeObjectKind::Texture { id, allocation }, .. }) => { - (id, allocation) - } + Some(FreeObject { + kind: FreeObjectKind::Texture { id, allocation }, + .. + }) => (id, allocation), _ => unreachable!(), }; @@ -275,7 +341,14 @@ impl GPUMemoryAllocator where D: Device { let id = self.next_texture_id; self.next_texture_id.0 += 1; - self.textures_in_use.insert(id, TextureAllocation { texture, descriptor, tag }); + self.textures_in_use.insert( + id, + TextureAllocation { + texture, + descriptor, + tag, + }, + ); self.bytes_allocated += byte_size; self.bytes_committed += byte_size; @@ -283,12 +356,13 @@ impl GPUMemoryAllocator where D: Device { id } - pub fn allocate_framebuffer(&mut self, - device: &D, - size: Vector2I, - format: TextureFormat, - tag: FramebufferTag) - -> FramebufferID { + pub fn allocate_framebuffer( + &mut self, + device: &D, + size: Vector2I, + format: TextureFormat, + tag: FramebufferTag, + ) -> FramebufferID { let descriptor = TextureDescriptor { width: size.x() as u32, height: size.y() as u32, @@ -298,15 +372,16 @@ impl GPUMemoryAllocator where D: Device { for free_object_index in 0..self.free_objects.len() { match self.free_objects[free_object_index].kind { - FreeObjectKind::Framebuffer { ref allocation, .. } if allocation.descriptor == - descriptor => {} + FreeObjectKind::Framebuffer { ref allocation, .. } + if allocation.descriptor == descriptor => {} _ => continue, } let (id, mut allocation) = match self.free_objects.remove(free_object_index) { - Some(FreeObject { kind: FreeObjectKind::Framebuffer { id, allocation }, .. }) => { - (id, allocation) - } + Some(FreeObject { + kind: FreeObjectKind::Framebuffer { id, allocation }, + .. + }) => (id, allocation), _ => unreachable!(), }; @@ -323,11 +398,14 @@ impl GPUMemoryAllocator where D: Device { let id = self.next_framebuffer_id; self.next_framebuffer_id.0 += 1; - self.framebuffers_in_use.insert(id, FramebufferAllocation { - framebuffer, - descriptor, - tag, - }); + self.framebuffers_in_use.insert( + id, + FramebufferAllocation { + framebuffer, + descriptor, + tag, + }, + ); self.bytes_allocated += byte_size; self.bytes_committed += byte_size; @@ -339,8 +417,8 @@ impl GPUMemoryAllocator where D: Device { let now = Instant::now(); loop { match self.free_objects.front() { - Some(FreeObject { timestamp, .. }) if (now - *timestamp).as_secs_f32() >= - DECAY_TIME => {} + Some(FreeObject { timestamp, .. }) + if (now - *timestamp).as_secs_f32() >= DECAY_TIME => {} _ => break, } match self.free_objects.pop_front() { @@ -352,15 +430,24 @@ impl GPUMemoryAllocator where D: Device { debug!("purging general buffer: {}", allocation.size); self.bytes_allocated -= allocation.size; } - Some(FreeObject { kind: FreeObjectKind::IndexBuffer { allocation, .. }, .. }) => { + Some(FreeObject { + kind: FreeObjectKind::IndexBuffer { allocation, .. }, + .. + }) => { debug!("purging index buffer: {}", allocation.size); self.bytes_allocated -= allocation.size; } - Some(FreeObject { kind: FreeObjectKind::Texture { allocation, .. }, .. }) => { + Some(FreeObject { + kind: FreeObjectKind::Texture { allocation, .. }, + .. + }) => { debug!("purging texture: {:?}", allocation.descriptor); self.bytes_allocated -= allocation.descriptor.byte_size(); } - Some(FreeObject { kind: FreeObjectKind::Framebuffer { allocation, .. }, .. }) => { + Some(FreeObject { + kind: FreeObjectKind::Framebuffer { allocation, .. }, + .. + }) => { debug!("purging framebuffer: {:?}", allocation.descriptor); self.bytes_allocated -= allocation.descriptor.byte_size(); } @@ -369,9 +456,10 @@ impl GPUMemoryAllocator where D: Device { } pub fn free_general_buffer(&mut self, id: GeneralBufferID) { - let allocation = self.general_buffers_in_use - .remove(&id) - .expect("Attempted to free unallocated general buffer!"); + let allocation = self + .general_buffers_in_use + .remove(&id) + .expect("Attempted to free unallocated general buffer!"); self.bytes_committed -= allocation.size; self.free_objects.push_back(FreeObject { timestamp: Instant::now(), @@ -380,9 +468,10 @@ impl GPUMemoryAllocator where D: Device { } pub fn free_index_buffer(&mut self, id: IndexBufferID) { - let allocation = self.index_buffers_in_use - .remove(&id) - .expect("Attempted to free unallocated index buffer!"); + let allocation = self + .index_buffers_in_use + .remove(&id) + .expect("Attempted to free unallocated index buffer!"); self.bytes_committed -= allocation.size; self.free_objects.push_back(FreeObject { timestamp: Instant::now(), @@ -391,9 +480,10 @@ impl GPUMemoryAllocator where D: Device { } pub fn free_texture(&mut self, id: TextureID) { - let allocation = self.textures_in_use - .remove(&id) - .expect("Attempted to free unallocated texture!"); + let allocation = self + .textures_in_use + .remove(&id) + .expect("Attempted to free unallocated texture!"); let byte_size = allocation.descriptor.byte_size(); self.bytes_committed -= byte_size; self.free_objects.push_back(FreeObject { @@ -403,9 +493,10 @@ impl GPUMemoryAllocator where D: Device { } pub fn free_framebuffer(&mut self, id: FramebufferID) { - let allocation = self.framebuffers_in_use - .remove(&id) - .expect("Attempted to free unallocated framebuffer!"); + let allocation = self + .framebuffers_in_use + .remove(&id) + .expect("Attempted to free unallocated framebuffer!"); let byte_size = allocation.descriptor.byte_size(); self.bytes_committed -= byte_size; self.free_objects.push_back(FreeObject { @@ -450,7 +541,10 @@ impl GPUMemoryAllocator where D: Device { ids.sort(); for id in ids { let allocation = &self.general_buffers_in_use[&id]; - println!("id {:?}: {:?} ({:?} B)", id, allocation.tag, allocation.size); + println!( + "id {:?}: {:?} ({:?} B)", + id, allocation.tag, allocation.size + ); } println!("Index buffers:"); @@ -458,7 +552,10 @@ impl GPUMemoryAllocator where D: Device { ids.sort(); for id in ids { let allocation = &self.index_buffers_in_use[&id]; - println!("id {:?}: {:?} ({:?} B)", id, allocation.tag, allocation.size); + println!( + "id {:?}: {:?} ({:?} B)", + id, allocation.tag, allocation.size + ); } println!("Textures:"); @@ -466,13 +563,15 @@ impl GPUMemoryAllocator where D: Device { ids.sort(); for id in ids { let allocation = &self.textures_in_use[&id]; - println!("id {:?}: {:?} {:?}x{:?} {:?} ({:?} B)", - id, - allocation.tag, - allocation.descriptor.width, - allocation.descriptor.height, - allocation.descriptor.format, - allocation.descriptor.byte_size()); + println!( + "id {:?}: {:?} {:?}x{:?} {:?} ({:?} B)", + id, + allocation.tag, + allocation.descriptor.width, + allocation.descriptor.height, + allocation.descriptor.format, + allocation.descriptor.byte_size() + ); } println!("Framebuffers:"); @@ -480,13 +579,15 @@ impl GPUMemoryAllocator where D: Device { ids.sort(); for id in ids { let allocation = &self.framebuffers_in_use[&id]; - println!("id {:?}: {:?} {:?}x{:?} {:?} ({:?} B)", - id, - allocation.tag, - allocation.descriptor.width, - allocation.descriptor.height, - allocation.descriptor.format, - allocation.descriptor.byte_size()); + println!( + "id {:?}: {:?} {:?}x{:?} {:?} ({:?} B)", + id, + allocation.tag, + allocation.descriptor.width, + allocation.descriptor.height, + allocation.descriptor.format, + allocation.descriptor.byte_size() + ); } } } diff --git a/gpu/src/lib.rs b/gpu/src/lib.rs index 8a344c9d..ddbeaf33 100644 --- a/gpu/src/lib.rs +++ b/gpu/src/lib.rs @@ -22,7 +22,7 @@ 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_geometry::vector::{vec2i, Vector2I}; use pathfinder_resources::ResourceLoader; use pathfinder_simd::default::{F32x2, F32x4, I32x2}; use std::ops::Range; @@ -50,64 +50,95 @@ pub trait Device: Sized { fn device_name(&self) -> String; 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_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 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_texture_parameter(&self, program: &Self::Program, name: &str) -> Self::TextureParameter; fn get_image_parameter(&self, program: &Self::Program, name: &str) -> Self::ImageParameter; - 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 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 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 read_buffer(&self, buffer: &Self::Buffer, target: BufferTarget, range: Range) - -> Self::BufferDataReceiver; + fn read_pixels( + &self, + target: &RenderTarget, + viewport: RectI, + ) -> Self::TextureDataReceiver; + fn read_buffer( + &self, + buffer: &Self::Buffer, + target: BufferTarget, + range: Range, + ) -> Self::BufferDataReceiver; 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 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); @@ -121,11 +152,12 @@ pub trait Device: Sized { fn try_recv_buffer(&self, receiver: &Self::BufferDataReceiver) -> Option>; fn recv_buffer(&self, receiver: &Self::BufferDataReceiver) -> Vec; - fn create_texture_from_png(&self, - resources: &dyn ResourceLoader, - name: &str, - format: TextureFormat) - -> Self::Texture { + 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 { @@ -143,11 +175,13 @@ pub trait Device: Sized { } } - fn upload_png_to_texture(&self, - resources: &dyn ResourceLoader, - name: &str, - texture: &Self::Texture, - format: TextureFormat) { + fn upload_png_to_texture( + &self, + resources: &dyn ResourceLoader, + name: &str, + texture: &Self::Texture, + format: TextureFormat, + ) { let data = resources.slurp(&format!("textures/{}.png", name)).unwrap(); let image = image::load_from_memory_with_format(&data, ImageFormat::Png).unwrap(); match format { @@ -174,12 +208,10 @@ pub trait Device: Sized { 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::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)) } @@ -188,7 +220,10 @@ pub trait Device: Sized { } fn create_raster_program(&self, resources: &dyn ResourceLoader, name: &str) -> Self::Program { - let shaders = ProgramKind::Raster { vertex: name, fragment: name }; + let shaders = ProgramKind::Raster { + vertex: name, + fragment: name, + }; self.create_program_from_shader_names(resources, name, shaders) } @@ -253,10 +288,7 @@ pub enum ShaderKind { #[derive(Clone, Copy, Debug)] pub enum ProgramKind { - Raster { - vertex: T, - fragment: T, - }, + Raster { vertex: T, fragment: T }, Compute(T), } @@ -287,7 +319,10 @@ pub enum Primitive { } #[derive(Clone)] -pub struct RenderState<'a, D> where D: Device { +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, @@ -301,7 +336,10 @@ pub struct RenderState<'a, D> where D: Device { } #[derive(Clone)] -pub struct ComputeState<'a, D> where D: Device { +pub struct ComputeState<'a, D> +where + D: Device, +{ pub program: &'a D::Program, pub uniforms: &'a [UniformBinding<'a, D::Uniform>], pub textures: &'a [TextureBinding<'a, D::TextureParameter, D::Texture>], @@ -332,7 +370,10 @@ pub struct ClearOps { } #[derive(Clone, Copy, Debug)] -pub enum RenderTarget<'a, D> where D: Device { +pub enum RenderTarget<'a, D> +where + D: Device, +{ Default, Framebuffer(&'a D::Framebuffer), } @@ -537,8 +578,11 @@ pub enum ImageAccess { impl<'a> TextureDataRef<'a> { #[doc(hidden)] - pub fn check_and_extract_data_ptr(self, minimum_size: Vector2I, format: TextureFormat) - -> *const c_void { + 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, diff --git a/lottie/src/lib.rs b/lottie/src/lib.rs index 4b062cdb..b9e47b88 100644 --- a/lottie/src/lib.rs +++ b/lottie/src/lib.rs @@ -307,7 +307,10 @@ pub struct ShapeKeyframeProperty { impl Lottie { #[inline] - pub fn from_reader(reader: R) -> Result where R: Read { + pub fn from_reader(reader: R) -> Result + where + R: Read, + { serde_json::from_reader(reader) } } diff --git a/metal/src/lib.rs b/metal/src/lib.rs index 1755c2b5..d8917d4d 100644 --- a/metal/src/lib.rs +++ b/metal/src/lib.rs @@ -32,9 +32,14 @@ use libc::size_t; use metal::{self, Argument, ArgumentEncoder, BlitCommandEncoder, Buffer, CommandBuffer}; use metal::{CommandQueue, CompileOptions, ComputeCommandEncoder, ComputePipelineDescriptor}; use metal::{ComputePipelineState, CoreAnimationDrawable, CoreAnimationDrawableRef}; -use metal::{CoreAnimationLayer, CoreAnimationLayerRef, DepthStencilDescriptor, Device as NativeMetalDevice, DeviceRef, Function, Library}; +use metal::{ + CoreAnimationLayer, CoreAnimationLayerRef, DepthStencilDescriptor, Device as NativeMetalDevice, + DeviceRef, Function, Library, +}; use metal::{MTLArgument, MTLArgumentEncoder, MTLArgumentType, MTLBlendFactor, MTLBlendOperation}; -use metal::{MTLBlitOption, MTLClearColor, MTLColorWriteMask, MTLCompareFunction, MTLComputePipelineState}; +use metal::{ + MTLBlitOption, MTLClearColor, MTLColorWriteMask, MTLCompareFunction, MTLComputePipelineState, +}; use metal::{MTLDataType, MTLDevice, MTLIndexType, MTLLoadAction, MTLOrigin, MTLPixelFormat}; use metal::{MTLPrimitiveType, MTLRegion, MTLRenderPipelineReflection, MTLRenderPipelineState}; use metal::{MTLResourceOptions, MTLResourceUsage, MTLSamplerAddressMode, MTLSamplerMinMagFilter}; @@ -44,11 +49,11 @@ use metal::{RenderCommandEncoder, RenderCommandEncoderRef, RenderPassDescriptor} use metal::{RenderPassDescriptorRef, RenderPipelineColorAttachmentDescriptorRef}; use metal::{RenderPipelineDescriptor, RenderPipelineReflection, RenderPipelineReflectionRef}; use metal::{RenderPipelineState, SamplerDescriptor, SamplerState, StencilDescriptor}; -use metal::{StructMemberRef, StructType, StructTypeRef, TextureDescriptor, Texture, TextureRef}; +use metal::{StructMemberRef, StructType, StructTypeRef, Texture, TextureDescriptor, TextureRef}; use metal::{VertexAttribute, VertexAttributeRef, VertexDescriptor, VertexDescriptorRef}; use objc::runtime::{Class, Object}; use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::{Vector2I, vec2i}; +use pathfinder_geometry::vector::{vec2i, Vector2I}; use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode}; use pathfinder_gpu::{ComputeDimensions, ComputeState, DepthFunc, Device, FeatureLevel}; use pathfinder_gpu::{ImageAccess, Primitive, ProgramKind, RenderState, RenderTarget, ShaderKind}; @@ -127,41 +132,50 @@ struct Scope { impl MetalDevice { #[inline] pub unsafe fn new(device: D, texture: T) -> MetalDevice - where D: IntoMetalDevice, T: IntoTexture { + where + D: IntoMetalDevice, + T: IntoTexture, + { let device = device.into_metal_device(); let command_queue = device.new_command_queue(); - let samplers = (0..16).map(|sampling_flags_value| { - let sampling_flags = TextureSamplingFlags::from_bits(sampling_flags_value).unwrap(); - let sampler_descriptor = SamplerDescriptor::new(); - sampler_descriptor.set_support_argument_buffers(true); - sampler_descriptor.set_normalized_coordinates(true); - sampler_descriptor.set_min_filter( - if sampling_flags.contains(TextureSamplingFlags::NEAREST_MIN) { - MTLSamplerMinMagFilter::Nearest - } else { - MTLSamplerMinMagFilter::Linear - }); - sampler_descriptor.set_mag_filter( - if sampling_flags.contains(TextureSamplingFlags::NEAREST_MAG) { - MTLSamplerMinMagFilter::Nearest - } else { - MTLSamplerMinMagFilter::Linear - }); - sampler_descriptor.set_address_mode_s( - if sampling_flags.contains(TextureSamplingFlags::REPEAT_U) { - MTLSamplerAddressMode::Repeat - } else { - MTLSamplerAddressMode::ClampToEdge - }); - sampler_descriptor.set_address_mode_t( - if sampling_flags.contains(TextureSamplingFlags::REPEAT_V) { - MTLSamplerAddressMode::Repeat - } else { - MTLSamplerAddressMode::ClampToEdge - }); - device.new_sampler(&sampler_descriptor) - }).collect(); + let samplers = (0..16) + .map(|sampling_flags_value| { + let sampling_flags = TextureSamplingFlags::from_bits(sampling_flags_value).unwrap(); + let sampler_descriptor = SamplerDescriptor::new(); + sampler_descriptor.set_support_argument_buffers(true); + sampler_descriptor.set_normalized_coordinates(true); + sampler_descriptor.set_min_filter( + if sampling_flags.contains(TextureSamplingFlags::NEAREST_MIN) { + MTLSamplerMinMagFilter::Nearest + } else { + MTLSamplerMinMagFilter::Linear + }, + ); + sampler_descriptor.set_mag_filter( + if sampling_flags.contains(TextureSamplingFlags::NEAREST_MAG) { + MTLSamplerMinMagFilter::Nearest + } else { + MTLSamplerMinMagFilter::Linear + }, + ); + sampler_descriptor.set_address_mode_s( + if sampling_flags.contains(TextureSamplingFlags::REPEAT_U) { + MTLSamplerAddressMode::Repeat + } else { + MTLSamplerAddressMode::ClampToEdge + }, + ); + sampler_descriptor.set_address_mode_t( + if sampling_flags.contains(TextureSamplingFlags::REPEAT_V) { + MTLSamplerAddressMode::Repeat + } else { + MTLSamplerAddressMode::ClampToEdge + }, + ); + device.new_sampler(&sampler_descriptor) + }) + .collect(); let texture = texture.into_texture(&device); let framebuffer_size = vec2i(texture.width() as i32, texture.height() as i32); @@ -170,8 +184,7 @@ impl MetalDevice { let timer_query_shared_event = device.new_shared_event(); let buffer_upload_shared_event = device.new_shared_event(); - let dispatch_queue = Queue::create("graphics.pathfinder.queue", - QueueAttribute::Concurrent); + let dispatch_queue = Queue::create("graphics.pathfinder.queue", QueueAttribute::Concurrent); let shared_event_listener = SharedEventListener::new_from_dispatch_queue(&dispatch_queue); let buffer_upload_event_data = Arc::new(BufferUploadEventData { @@ -198,7 +211,10 @@ impl MetalDevice { } #[inline] - pub fn swap_texture(&mut self, new_texture: T) -> Texture where T: IntoTexture { + pub fn swap_texture(&mut self, new_texture: T) -> Texture + where + T: IntoTexture, + { unsafe { let new_texture = new_texture.into_texture(&self.device); mem::replace(&mut self.main_color_texture, new_texture) @@ -394,8 +410,12 @@ impl Device for MetalDevice { } } - fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef) - -> MetalTexture { + fn create_texture_from_data( + &self, + format: TextureFormat, + size: Vector2I, + data: TextureDataRef, + ) -> MetalTexture { let texture = self.create_texture(format, size); self.upload_to_texture(&texture, RectI::new(Vector2I::default(), size), data); texture @@ -405,7 +425,10 @@ impl Device for MetalDevice { let source = String::from_utf8(source.to_vec()).expect("Source wasn't valid UTF-8!"); let compile_options = CompileOptions::new(); - let library = self.device.new_library_with_source(&source, &compile_options).unwrap(); + let library = self + .device + .new_library_with_source(&source, &compile_options) + .unwrap(); let function = library.get_function("main0", None).unwrap(); MetalShader { @@ -424,14 +447,17 @@ impl Device for MetalDevice { } } - fn bind_buffer(&self, - vertex_array: &MetalVertexArray, - buffer: &MetalBuffer, - target: BufferTarget) { + fn bind_buffer( + &self, + vertex_array: &MetalVertexArray, + buffer: &MetalBuffer, + target: BufferTarget, + ) { match target { - BufferTarget::Vertex => { - vertex_array.vertex_buffers.borrow_mut().push((*buffer).clone()) - } + BufferTarget::Vertex => vertex_array + .vertex_buffers + .borrow_mut() + .push((*buffer).clone()), BufferTarget::Index => { *vertex_array.index_buffer.borrow_mut() = Some((*buffer).clone()) } @@ -439,17 +465,26 @@ impl Device for MetalDevice { } } - fn create_program_from_shaders(&self, - _: &dyn ResourceLoader, - _: &str, - shaders: ProgramKind) - -> MetalProgram { + fn create_program_from_shaders( + &self, + _: &dyn ResourceLoader, + _: &str, + shaders: ProgramKind, + ) -> MetalProgram { match shaders { - ProgramKind::Raster { vertex: vertex_shader, fragment: fragment_shader } => { - MetalProgram::Raster(MetalRasterProgram { vertex_shader, fragment_shader }) - } + ProgramKind::Raster { + vertex: vertex_shader, + fragment: fragment_shader, + } => MetalProgram::Raster(MetalRasterProgram { + vertex_shader, + fragment_shader, + }), ProgramKind::Compute(shader) => { - let local_size = MTLSize { width: 0, height: 0, depth: 0 }; + let local_size = MTLSize { + width: 0, + height: 0, + depth: 0, + }; MetalProgram::Compute(MetalComputeProgram { shader, local_size }) } } @@ -457,13 +492,15 @@ impl Device for MetalDevice { // FIXME(pcwalton): Is there a way to introspect the shader to find `gl_WorkGroupSize`? That // would obviate the need for this function. - fn set_compute_program_local_size(&self, - program: &mut MetalProgram, - new_local_size: ComputeDimensions) { + fn set_compute_program_local_size( + &self, + program: &mut MetalProgram, + new_local_size: ComputeDimensions, + ) { match *program { - MetalProgram::Compute(MetalComputeProgram { ref mut local_size, .. }) => { - *local_size = new_local_size.to_metal_size() - } + MetalProgram::Compute(MetalComputeProgram { + ref mut local_size, .. + }) => *local_size = new_local_size.to_metal_size(), _ => panic!("Program was not a compute program!"), } } @@ -471,46 +508,64 @@ impl Device for MetalDevice { fn get_vertex_attr(&self, program: &MetalProgram, name: &str) -> Option { // TODO(pcwalton): Cache the function? let attributes = match *program { - MetalProgram::Raster(MetalRasterProgram { ref vertex_shader, .. }) => { - vertex_shader.function.real_vertex_attributes() - } + MetalProgram::Raster(MetalRasterProgram { + ref vertex_shader, .. + }) => vertex_shader.function.real_vertex_attributes(), _ => unreachable!(), }; for attribute_index in 0..attributes.len() { let attribute = attributes.object_at(attribute_index); let this_name = attribute.name().as_bytes(); if this_name[0] == b'a' && this_name[1..] == *name.as_bytes() { - return Some(attribute.retain()) + return Some(attribute.retain()); } } None } fn get_uniform(&self, _: &Self::Program, name: &str) -> MetalUniform { - MetalUniform { indices: RefCell::new(None), name: name.to_owned() } + MetalUniform { + indices: RefCell::new(None), + name: name.to_owned(), + } } fn get_texture_parameter(&self, _: &Self::Program, name: &str) -> MetalTextureParameter { - MetalTextureParameter { indices: RefCell::new(None), name: name.to_owned() } + MetalTextureParameter { + indices: RefCell::new(None), + name: name.to_owned(), + } } fn get_image_parameter(&self, _: &Self::Program, name: &str) -> MetalImageParameter { - MetalImageParameter { indices: RefCell::new(None), name: name.to_owned() } + MetalImageParameter { + indices: RefCell::new(None), + name: name.to_owned(), + } } fn get_storage_buffer(&self, _: &Self::Program, name: &str, _: u32) -> MetalStorageBuffer { - MetalStorageBuffer { indices: RefCell::new(None), name: name.to_owned() } + MetalStorageBuffer { + indices: RefCell::new(None), + name: name.to_owned(), + } } - fn configure_vertex_attr(&self, - vertex_array: &MetalVertexArray, - attr: &VertexAttribute, - descriptor: &VertexAttrDescriptor) { + fn configure_vertex_attr( + &self, + vertex_array: &MetalVertexArray, + attr: &VertexAttribute, + descriptor: &VertexAttrDescriptor, + ) { debug_assert_ne!(descriptor.stride, 0); let attribute_index = attr.attribute_index(); - let attr_info = vertex_array.descriptor.attributes().object_at(attribute_index).unwrap(); + let attr_info = vertex_array + .descriptor + .attributes() + .object_at(attribute_index) + .unwrap(); let format = match (descriptor.class, descriptor.attr_type, descriptor.size) { (VertexAttrClass::Int, VertexAttrType::I8, 2) => MTLVertexFormat::Char2, (VertexAttrClass::Int, VertexAttrType::I8, 3) => MTLVertexFormat::Char3, @@ -527,15 +582,9 @@ impl Device for MetalDevice { (VertexAttrClass::FloatNorm, VertexAttrType::U8, 4) => { MTLVertexFormat::UChar4Normalized } - (VertexAttrClass::FloatNorm, VertexAttrType::I8, 2) => { - MTLVertexFormat::Char2Normalized - } - (VertexAttrClass::FloatNorm, VertexAttrType::I8, 3) => { - MTLVertexFormat::Char3Normalized - } - (VertexAttrClass::FloatNorm, VertexAttrType::I8, 4) => { - MTLVertexFormat::Char4Normalized - } + (VertexAttrClass::FloatNorm, VertexAttrType::I8, 2) => MTLVertexFormat::Char2Normalized, + (VertexAttrClass::FloatNorm, VertexAttrType::I8, 3) => MTLVertexFormat::Char3Normalized, + (VertexAttrClass::FloatNorm, VertexAttrType::I8, 4) => MTLVertexFormat::Char4Normalized, (VertexAttrClass::Int, VertexAttrType::I16, 2) => MTLVertexFormat::Short2, (VertexAttrClass::Int, VertexAttrType::I16, 3) => MTLVertexFormat::Short3, (VertexAttrClass::Int, VertexAttrType::I16, 4) => MTLVertexFormat::Short4, @@ -567,9 +616,7 @@ impl Device for MetalDevice { (VertexAttrClass::Int, VertexAttrType::I8, 1) => MTLVertexFormat::Char, (VertexAttrClass::Int, VertexAttrType::U8, 1) => MTLVertexFormat::UChar, (VertexAttrClass::FloatNorm, VertexAttrType::I8, 1) => MTLVertexFormat::CharNormalized, - (VertexAttrClass::FloatNorm, VertexAttrType::U8, 1) => { - MTLVertexFormat::UCharNormalized - } + (VertexAttrClass::FloatNorm, VertexAttrType::U8, 1) => MTLVertexFormat::UCharNormalized, (VertexAttrClass::Int, VertexAttrType::I16, 1) => MTLVertexFormat::Short, (VertexAttrClass::Int, VertexAttrType::I32, 1) => MTLVertexFormat::Int, (VertexAttrClass::Int, VertexAttrType::U16, 1) => MTLVertexFormat::UShort, @@ -580,10 +627,10 @@ impl Device for MetalDevice { MTLVertexFormat::ShortNormalized } (attr_class, attr_type, attr_size) => { - panic!("Unsupported vertex class/type/size combination: {:?}/{:?}/{}!", - attr_class, - attr_type, - attr_size) + panic!( + "Unsupported vertex class/type/size combination: {:?}/{:?}/{}!", + attr_class, attr_type, attr_size + ) } }; attr_info.set_format(format); @@ -593,7 +640,11 @@ impl Device for MetalDevice { // FIXME(pcwalton): Metal separates out per-buffer info from per-vertex info, while our // GL-like API does not. So we end up setting this state over and over again. Not great. - let layout = vertex_array.descriptor.layouts().object_at(buffer_index).unwrap(); + let layout = vertex_array + .descriptor + .layouts() + .object_at(buffer_index) + .unwrap(); if descriptor.divisor == 0 { layout.set_step_function(MTLVertexStepFunction::PerVertex); layout.set_step_rate(1); @@ -619,10 +670,7 @@ impl Device for MetalDevice { } } - fn allocate_buffer(&self, - buffer: &MetalBuffer, - data: BufferData, - target: BufferTarget) { + fn allocate_buffer(&self, buffer: &MetalBuffer, data: BufferData, target: BufferTarget) { let options = buffer.mode.to_metal_resource_options(); let length = match data { BufferData::Uninitialized(size) => size, @@ -632,9 +680,9 @@ impl Device for MetalDevice { let new_buffer = self.device.new_buffer(byte_size, options); *buffer.allocations.borrow_mut() = BufferAllocations { - private: Some(new_buffer), - shared: None, - byte_size, + private: Some(new_buffer), + shared: None, + byte_size, }; match data { @@ -643,11 +691,13 @@ impl Device for MetalDevice { } } - fn upload_to_buffer(&self, - dest_buffer: &MetalBuffer, - start: usize, - data: &[T], - _: BufferTarget) { + fn upload_to_buffer( + &self, + dest_buffer: &MetalBuffer, + start: usize, + data: &[T], + _: BufferTarget, + ) { if data.is_empty() { return; } @@ -660,10 +710,12 @@ impl Device for MetalDevice { let byte_size = (data.len() * mem::size_of::()) as u64; if dest_allocations.shared.is_none() { - let resource_options = MTLResourceOptions::CPUCacheModeWriteCombined | - MTLResourceOptions::StorageModeShared; + let resource_options = MTLResourceOptions::CPUCacheModeWriteCombined + | MTLResourceOptions::StorageModeShared; dest_allocations.shared = Some(StagingBuffer { - buffer: self.device.new_buffer(dest_allocations.byte_size, resource_options), + buffer: self + .device + .new_buffer(dest_allocations.byte_size, resource_options), event_value: 0, }); } @@ -680,25 +732,29 @@ impl Device for MetalDevice { ptr::copy_nonoverlapping( data.as_ptr() as *const u8, (staging_buffer.buffer.contents() as *mut u8).offset(byte_start as isize), - byte_size as usize) + byte_size as usize, + ) } staging_buffer.event_value = self.next_buffer_upload_event_value.get(); - self.next_buffer_upload_event_value.set(staging_buffer.event_value + 1); + self.next_buffer_upload_event_value + .set(staging_buffer.event_value + 1); { let scopes = self.scopes.borrow(); let command_buffer = &scopes.last().unwrap().command_buffer; let blit_command_encoder = command_buffer.real_new_blit_command_encoder(); - blit_command_encoder.copy_from_buffer(&staging_buffer.buffer, - byte_start, - &dest_private_buffer, - byte_start, - byte_size); + blit_command_encoder.copy_from_buffer( + &staging_buffer.buffer, + byte_start, + &dest_private_buffer, + byte_start, + byte_size, + ); blit_command_encoder.end_encoding(); - command_buffer.encode_signal_event(&self.buffer_upload_shared_event, - staging_buffer.event_value); + command_buffer + .encode_signal_event(&self.buffer_upload_shared_event, staging_buffer.event_value); let buffer_upload_event_data = self.buffer_upload_event_data.clone(); let event_value = staging_buffer.event_value; @@ -707,9 +763,11 @@ impl Device for MetalDevice { *mutex = (*mutex).max(event_value); buffer_upload_event_data.cond.notify_all(); }); - self.buffer_upload_shared_event.notify_listener_at_value(&self.shared_event_listener, - staging_buffer.event_value, - listener_block.copy()); + self.buffer_upload_shared_event.notify_listener_at_value( + &self.shared_event_listener, + staging_buffer.event_value, + listener_block.copy(), + ); } // Flush to avoid deadlock. @@ -739,7 +797,10 @@ impl Device for MetalDevice { } fn texture_size(&self, texture: &MetalTexture) -> Vector2I { - vec2i(texture.private_texture.width() as i32, texture.private_texture.height() as i32) + vec2i( + texture.private_texture.width() as i32, + texture.private_texture.height() as i32, + ) } fn set_texture_sampling_mode(&self, texture: &MetalTexture, flags: TextureSamplingFlags) { @@ -748,20 +809,22 @@ impl Device for MetalDevice { fn upload_to_texture(&self, dest_texture: &MetalTexture, rect: RectI, data: TextureDataRef) { let scopes = self.scopes.borrow(); - let command_buffer = &scopes.last() - .expect("Must call `begin_commands()` first!") - .command_buffer; + let command_buffer = &scopes + .last() + .expect("Must call `begin_commands()` first!") + .command_buffer; let texture_size = self.texture_size(dest_texture); - let texture_format = self.texture_format(&dest_texture.private_texture) - .expect("Unexpected texture format!"); + let texture_format = self + .texture_format(&dest_texture.private_texture) + .expect("Unexpected texture format!"); let bytes_per_pixel = texture_format.bytes_per_pixel() as u64; let texture_byte_size = texture_size.area() as u64 * bytes_per_pixel; let mut src_shared_buffer = dest_texture.shared_buffer.borrow_mut(); if src_shared_buffer.is_none() { - let resource_options = MTLResourceOptions::CPUCacheModeWriteCombined | - MTLResourceOptions::StorageModeShared; + let resource_options = MTLResourceOptions::CPUCacheModeWriteCombined + | MTLResourceOptions::StorageModeShared; *src_shared_buffer = Some(self.device.new_buffer(texture_byte_size, resource_options)); } @@ -776,11 +839,13 @@ impl Device for MetalDevice { for src_y in 0..rect.height() { let dest_y = src_y + rect.origin_y(); let src_offset = src_y as isize * src_stride as isize; - let dest_offset = dest_y as isize * dest_stride as isize + - rect.origin_x() as isize * bytes_per_pixel as isize; - ptr::copy_nonoverlapping(texture_data_ptr.offset(src_offset), - dest_contents.offset(dest_offset), - src_stride as usize); + let dest_offset = dest_y as isize * dest_stride as isize + + rect.origin_x() as isize * bytes_per_pixel as isize; + ptr::copy_nonoverlapping( + texture_data_ptr.offset(src_offset), + dest_contents.offset(dest_offset), + src_stride as usize, + ); } } @@ -789,26 +854,35 @@ impl Device for MetalDevice { height: rect.height() as u64, depth: 1, }; - let dest_origin = MTLOrigin { x: rect.origin_x() as u64, y: rect.origin_y() as u64, z: 0 }; - let dest_byte_offset = rect.origin_y() as u64 * src_stride as u64 + - rect.origin_x() as u64 * bytes_per_pixel as u64; + let dest_origin = MTLOrigin { + x: rect.origin_x() as u64, + y: rect.origin_y() as u64, + z: 0, + }; + let dest_byte_offset = rect.origin_y() as u64 * src_stride as u64 + + rect.origin_x() as u64 * bytes_per_pixel as u64; let blit_command_encoder = command_buffer.real_new_blit_command_encoder(); - blit_command_encoder.copy_from_buffer_to_texture(&src_shared_buffer, - dest_byte_offset, - dest_stride, - 0, - src_size, - &dest_texture.private_texture, - 0, - 0, - dest_origin, - MTLBlitOption::empty()); + blit_command_encoder.copy_from_buffer_to_texture( + &src_shared_buffer, + dest_byte_offset, + dest_stride, + 0, + src_size, + &dest_texture.private_texture, + 0, + 0, + dest_origin, + MTLBlitOption::empty(), + ); blit_command_encoder.end_encoding(); } - fn read_pixels(&self, target: &RenderTarget, viewport: RectI) - -> MetalTextureDataReceiver { + fn read_pixels( + &self, + target: &RenderTarget, + viewport: RectI, + ) -> MetalTextureDataReceiver { let texture = self.render_target_color_texture(target); let texture_data_receiver = MetalTextureDataReceiver(Arc::new(MetalTextureDataReceiverInfo { @@ -831,8 +905,12 @@ impl Device for MetalDevice { texture_data_receiver } - fn read_buffer(&self, src_buffer: &MetalBuffer, _: BufferTarget, range: Range) - -> MetalBufferDataReceiver { + fn read_buffer( + &self, + src_buffer: &MetalBuffer, + _: BufferTarget, + range: Range, + ) -> MetalBufferDataReceiver { let buffer_data_receiver; { let scopes = self.scopes.borrow(); @@ -840,15 +918,18 @@ impl Device for MetalDevice { let mut src_allocations = src_buffer.allocations.borrow_mut(); let src_allocations = &mut *src_allocations; - let src_private_buffer = src_allocations.private - .as_ref() - .expect("Private buffer not allocated!"); + let src_private_buffer = src_allocations + .private + .as_ref() + .expect("Private buffer not allocated!"); if src_allocations.shared.is_none() { - let resource_options = MTLResourceOptions::CPUCacheModeWriteCombined | - MTLResourceOptions::StorageModeShared; + let resource_options = MTLResourceOptions::CPUCacheModeWriteCombined + | MTLResourceOptions::StorageModeShared; src_allocations.shared = Some(StagingBuffer { - buffer: self.device.new_buffer(src_allocations.byte_size, resource_options), + buffer: self + .device + .new_buffer(src_allocations.byte_size, resource_options), event_value: 0, }); } @@ -856,11 +937,13 @@ impl Device for MetalDevice { let staging_buffer = src_allocations.shared.as_ref().unwrap(); let byte_size = (range.end - range.start) as u64; let blit_command_encoder = command_buffer.real_new_blit_command_encoder(); - blit_command_encoder.copy_from_buffer(src_private_buffer, - 0, - &staging_buffer.buffer, - range.start as u64, - byte_size); + blit_command_encoder.copy_from_buffer( + src_private_buffer, + 0, + &staging_buffer.buffer, + range.start as u64, + byte_size, + ); buffer_data_receiver = MetalBufferDataReceiver(Arc::new(MetalBufferDataReceiverInfo { mutex: Mutex::new(MetalDataReceiverState::Pending), @@ -891,7 +974,7 @@ impl Device for MetalDevice { loop { let buffer_data = try_recv_data_with_guard(&mut guard); if let Some(buffer_data) = buffer_data { - return buffer_data + return buffer_data; } guard = buffer_data_receiver.0.cond.wait(guard).unwrap(); } @@ -901,7 +984,10 @@ impl Device for MetalDevice { unsafe { let autorelease_pool = NSAutoreleasePool::new(nil); let command_buffer = self.command_queue.new_command_buffer_retained(); - self.scopes.borrow_mut().push(Scope { autorelease_pool, command_buffer }) + self.scopes.borrow_mut().push(Scope { + autorelease_pool, + command_buffer, + }) } } @@ -925,43 +1011,51 @@ impl Device for MetalDevice { let primitive = render_state.primitive.to_metal_primitive(); let index_type = MTLIndexType::UInt32; let index_count = index_count as u64; - let index_buffer = render_state.vertex_array - .index_buffer - .borrow(); - let index_buffer = index_buffer.as_ref().expect("No index buffer bound to VAO!"); + let index_buffer = render_state.vertex_array.index_buffer.borrow(); + let index_buffer = index_buffer + .as_ref() + .expect("No index buffer bound to VAO!"); let index_buffer = index_buffer.allocations.borrow(); - let index_buffer = index_buffer.private.as_ref().expect("Index buffer not allocated!"); + let index_buffer = index_buffer + .private + .as_ref() + .expect("Index buffer not allocated!"); encoder.draw_indexed_primitives(primitive, index_count, index_type, index_buffer, 0); encoder.end_encoding(); } - fn draw_elements_instanced(&self, - index_count: u32, - instance_count: u32, - render_state: &RenderState) { + fn draw_elements_instanced( + &self, + index_count: u32, + instance_count: u32, + render_state: &RenderState, + ) { let encoder = self.prepare_to_draw(render_state); let primitive = render_state.primitive.to_metal_primitive(); let index_type = MTLIndexType::UInt32; - let index_buffer = render_state.vertex_array - .index_buffer - .borrow(); - let index_buffer = index_buffer.as_ref().expect("No index buffer bound to VAO!"); + let index_buffer = render_state.vertex_array.index_buffer.borrow(); + let index_buffer = index_buffer + .as_ref() + .expect("No index buffer bound to VAO!"); let index_buffer = index_buffer.allocations.borrow(); - let index_buffer = index_buffer.private.as_ref().expect("Index buffer not allocated!"); + let index_buffer = index_buffer + .private + .as_ref() + .expect("Index buffer not allocated!"); - encoder.draw_indexed_primitives_instanced(primitive, - index_count as u64, - index_type, - index_buffer, - 0, - instance_count as u64); + encoder.draw_indexed_primitives_instanced( + primitive, + index_count as u64, + index_type, + index_buffer, + 0, + instance_count as u64, + ); encoder.end_encoding(); } - fn dispatch_compute(&self, - size: ComputeDimensions, - compute_state: &ComputeState) { + fn dispatch_compute(&self, size: ComputeDimensions, compute_state: &ComputeState) { let scopes = self.scopes.borrow(); let command_buffer = &scopes.last().unwrap().command_buffer; @@ -979,8 +1073,8 @@ impl Device for MetalDevice { if program.shader.arguments.borrow().is_none() { // FIXME(pcwalton): Factor these raw Objective-C method calls out into a trait. let mut reflection: *mut Object = ptr::null_mut(); - let reflection_options = MTLPipelineOption::ArgumentInfo | - MTLPipelineOption::BufferTypeInfo; + let reflection_options = + MTLPipelineOption::ArgumentInfo | MTLPipelineOption::BufferTypeInfo; let mut error: *mut Object = ptr::null_mut(); let raw_compute_pipeline_state: *mut MTLComputePipelineState = msg_send![ self.device.as_ptr(), @@ -1030,22 +1124,26 @@ impl Device for MetalDevice { })); let captured_query = Arc::downgrade(&query.0); - query.0.mutex.lock().unwrap().start_block = Some(ConcreteBlock::new(move |_: *mut Object, - _: u64| { - let start_time = Instant::now(); - let query = captured_query.upgrade().unwrap(); - let mut guard = query.mutex.lock().unwrap(); - guard.start_time = Some(start_time); - }).copy()); + query.0.mutex.lock().unwrap().start_block = Some( + ConcreteBlock::new(move |_: *mut Object, _: u64| { + let start_time = Instant::now(); + let query = captured_query.upgrade().unwrap(); + let mut guard = query.mutex.lock().unwrap(); + guard.start_time = Some(start_time); + }) + .copy(), + ); let captured_query = Arc::downgrade(&query.0); - query.0.mutex.lock().unwrap().end_block = Some(ConcreteBlock::new(move |_: *mut Object, - _: u64| { - let end_time = Instant::now(); - let query = captured_query.upgrade().unwrap(); - let mut guard = query.mutex.lock().unwrap(); - guard.end_time = Some(end_time); - query.cond.notify_all(); - }).copy()); + query.0.mutex.lock().unwrap().end_block = Some( + ConcreteBlock::new(move |_: *mut Object, _: u64| { + let end_time = Instant::now(); + let query = captured_query.upgrade().unwrap(); + let mut guard = query.mutex.lock().unwrap(); + guard.end_time = Some(end_time); + query.cond.notify_all(); + }) + .copy(), + ); query } @@ -1055,10 +1153,11 @@ impl Device for MetalDevice { self.next_timer_query_event_value.set(start_event_value + 2); let mut guard = query.0.mutex.lock().unwrap(); guard.start_event_value = start_event_value; - self.timer_query_shared_event - .notify_listener_at_value(&self.shared_event_listener, - start_event_value, - (*guard.start_block.as_ref().unwrap()).clone()); + self.timer_query_shared_event.notify_listener_at_value( + &self.shared_event_listener, + start_event_value, + (*guard.start_block.as_ref().unwrap()).clone(), + ); self.scopes .borrow_mut() .last() @@ -1069,10 +1168,11 @@ impl Device for MetalDevice { fn end_timer_query(&self, query: &MetalTimerQuery) { let guard = query.0.mutex.lock().unwrap(); - self.timer_query_shared_event - .notify_listener_at_value(&self.shared_event_listener, - guard.start_event_value + 1, - (*guard.end_block.as_ref().unwrap()).clone()); + self.timer_query_shared_event.notify_listener_at_value( + &self.shared_event_listener, + guard.start_event_value + 1, + (*guard.end_block.as_ref().unwrap()).clone(), + ); self.scopes .borrow_mut() .last() @@ -1090,7 +1190,7 @@ impl Device for MetalDevice { loop { let duration = try_recv_timer_query_with_guard(&mut guard); if let Some(duration) = duration { - return duration + return duration; } guard = query.0.cond.wait(guard).unwrap(); } @@ -1105,7 +1205,7 @@ impl Device for MetalDevice { loop { let texture_data = try_recv_data_with_guard(&mut guard); if let Some(texture_data) = texture_data { - return texture_data + return texture_data; } guard = receiver.0.cond.wait(guard).unwrap(); } @@ -1168,7 +1268,7 @@ impl MetalDevice { let argument = arguments.object_at(argument_index); let argument_name = argument.name(); if argument_name == &main_name { - return Some(MetalUniformIndex(argument.index())) + return Some(MetalUniformIndex(argument.index())); } } None @@ -1208,14 +1308,17 @@ impl MetalDevice { let argument = arguments.object_at(argument_index); let argument_name = argument.name(); if argument_name == &main_name { - return Some(MetalImageIndex(argument.index())) + return Some(MetalImageIndex(argument.index())); } } None } - fn get_storage_buffer_index(&self, shader: &MetalShader, name: &str) - -> Option { + fn get_storage_buffer_index( + &self, + shader: &MetalShader, + name: &str, + ) -> Option { let uniforms = shader.arguments.borrow(); let arguments = match *uniforms { None => panic!("get_storage_buffer_index() called before reflection!"), @@ -1241,9 +1344,11 @@ impl MetalDevice { main_argument.map(MetalStorageBufferIndex) } - fn populate_uniform_indices_if_necessary(&self, - uniform: &MetalUniform, - program: &MetalProgram) { + fn populate_uniform_indices_if_necessary( + &self, + uniform: &MetalUniform, + program: &MetalProgram, + ) { let mut indices = uniform.indices.borrow_mut(); if indices.is_some() { return; @@ -1253,12 +1358,10 @@ impl MetalDevice { MetalProgram::Raster(MetalRasterProgram { ref vertex_shader, ref fragment_shader, - }) => { - Some(MetalUniformIndices(ProgramKind::Raster { - vertex: self.get_uniform_index(vertex_shader, &uniform.name), - fragment: self.get_uniform_index(fragment_shader, &uniform.name), - })) - } + }) => Some(MetalUniformIndices(ProgramKind::Raster { + vertex: self.get_uniform_index(vertex_shader, &uniform.name), + fragment: self.get_uniform_index(fragment_shader, &uniform.name), + })), MetalProgram::Compute(MetalComputeProgram { ref shader, .. }) => { let uniform_index = self.get_uniform_index(shader, &uniform.name); Some(MetalUniformIndices(ProgramKind::Compute(uniform_index))) @@ -1266,9 +1369,11 @@ impl MetalDevice { } } - fn populate_texture_indices_if_necessary(&self, - texture_parameter: &MetalTextureParameter, - program: &MetalProgram) { + fn populate_texture_indices_if_necessary( + &self, + texture_parameter: &MetalTextureParameter, + program: &MetalProgram, + ) { let mut indices = texture_parameter.indices.borrow_mut(); if indices.is_some() { return; @@ -1278,12 +1383,10 @@ impl MetalDevice { MetalProgram::Raster(MetalRasterProgram { ref vertex_shader, ref fragment_shader, - }) => { - Some(MetalTextureIndices(ProgramKind::Raster { - vertex: self.get_texture_index(vertex_shader, &texture_parameter.name), - fragment: self.get_texture_index(fragment_shader, &texture_parameter.name), - })) - } + }) => Some(MetalTextureIndices(ProgramKind::Raster { + vertex: self.get_texture_index(vertex_shader, &texture_parameter.name), + fragment: self.get_texture_index(fragment_shader, &texture_parameter.name), + })), MetalProgram::Compute(MetalComputeProgram { ref shader, .. }) => { let image_index = self.get_texture_index(shader, &texture_parameter.name); Some(MetalTextureIndices(ProgramKind::Compute(image_index))) @@ -1291,9 +1394,11 @@ impl MetalDevice { } } - fn populate_image_indices_if_necessary(&self, - image_parameter: &MetalImageParameter, - program: &MetalProgram) { + fn populate_image_indices_if_necessary( + &self, + image_parameter: &MetalImageParameter, + program: &MetalProgram, + ) { let mut indices = image_parameter.indices.borrow_mut(); if indices.is_some() { return; @@ -1303,12 +1408,10 @@ impl MetalDevice { MetalProgram::Raster(MetalRasterProgram { ref vertex_shader, ref fragment_shader, - }) => { - Some(MetalImageIndices(ProgramKind::Raster { - vertex: self.get_image_index(vertex_shader, &image_parameter.name), - fragment: self.get_image_index(fragment_shader, &image_parameter.name), - })) - } + }) => Some(MetalImageIndices(ProgramKind::Raster { + vertex: self.get_image_index(vertex_shader, &image_parameter.name), + fragment: self.get_image_index(fragment_shader, &image_parameter.name), + })), MetalProgram::Compute(MetalComputeProgram { ref shader, .. }) => { let image_index = self.get_image_index(shader, &image_parameter.name); Some(MetalImageIndices(ProgramKind::Compute(image_index))) @@ -1316,9 +1419,11 @@ impl MetalDevice { } } - fn populate_storage_buffer_indices_if_necessary(&self, - storage_buffer: &MetalStorageBuffer, - program: &MetalProgram) { + fn populate_storage_buffer_indices_if_necessary( + &self, + storage_buffer: &MetalStorageBuffer, + program: &MetalProgram, + ) { let mut indices = storage_buffer.indices.borrow_mut(); if indices.is_some() { return; @@ -1328,39 +1433,40 @@ impl MetalDevice { MetalProgram::Raster(MetalRasterProgram { ref vertex_shader, ref fragment_shader, - }) => { - Some(MetalStorageBufferIndices(ProgramKind::Raster { - vertex: self.get_storage_buffer_index(vertex_shader, &storage_buffer.name), - fragment: self.get_storage_buffer_index(fragment_shader, &storage_buffer.name), - })) - } + }) => Some(MetalStorageBufferIndices(ProgramKind::Raster { + vertex: self.get_storage_buffer_index(vertex_shader, &storage_buffer.name), + fragment: self.get_storage_buffer_index(fragment_shader, &storage_buffer.name), + })), MetalProgram::Compute(MetalComputeProgram { ref shader, .. }) => { - let storage_buffer_index = self.get_storage_buffer_index(shader, - &storage_buffer.name); - Some(MetalStorageBufferIndices(ProgramKind::Compute(storage_buffer_index))) + let storage_buffer_index = + self.get_storage_buffer_index(shader, &storage_buffer.name); + Some(MetalStorageBufferIndices(ProgramKind::Compute( + storage_buffer_index, + ))) } } } - fn render_target_color_texture(&self, render_target: &RenderTarget) - -> Texture { + fn render_target_color_texture(&self, render_target: &RenderTarget) -> Texture { match *render_target { - RenderTarget::Default {..} => self.main_color_texture.retain(), + RenderTarget::Default { .. } => self.main_color_texture.retain(), RenderTarget::Framebuffer(framebuffer) => framebuffer.0.private_texture.retain(), } } - fn render_target_depth_texture(&self, render_target: &RenderTarget) - -> Option { + fn render_target_depth_texture( + &self, + render_target: &RenderTarget, + ) -> Option { match *render_target { - RenderTarget::Default {..} => Some(self.main_depth_stencil_texture.retain()), + RenderTarget::Default { .. } => Some(self.main_depth_stencil_texture.retain()), RenderTarget::Framebuffer(_) => None, } } fn render_target_has_depth(&self, render_target: &RenderTarget) -> bool { match *render_target { - RenderTarget::Default {..} => true, + RenderTarget::Default { .. } => true, RenderTarget::Framebuffer(_) => false, } } @@ -1389,16 +1495,15 @@ impl MetalDevice { let render_pipeline_descriptor = RenderPipelineDescriptor::new(); render_pipeline_descriptor.set_vertex_function(Some(&program.vertex_shader.function)); render_pipeline_descriptor.set_fragment_function(Some(&program.fragment_shader.function)); - render_pipeline_descriptor.set_vertex_descriptor(Some(&render_state.vertex_array - .descriptor)); + render_pipeline_descriptor + .set_vertex_descriptor(Some(&render_state.vertex_array.descriptor)); // Create render pipeline state. - let pipeline_color_attachment = - render_pipeline_descriptor.color_attachments() - .object_at(0) - .expect("Where's the color attachment?"); - self.prepare_pipeline_color_attachment_for_render(pipeline_color_attachment, - render_state); + let pipeline_color_attachment = render_pipeline_descriptor + .color_attachments() + .object_at(0) + .expect("Where's the color attachment?"); + self.prepare_pipeline_color_attachment_for_render(pipeline_color_attachment, render_state); if self.render_target_has_depth(render_state.target) { let depth_stencil_format = MTLPixelFormat::Depth32Float_Stencil8; @@ -1406,14 +1511,16 @@ impl MetalDevice { render_pipeline_descriptor.set_stencil_attachment_pixel_format(depth_stencil_format); } - let render_pipeline_state = if program.vertex_shader.arguments.borrow().is_none() || - program.fragment_shader.arguments.borrow().is_none() { - let reflection_options = MTLPipelineOption::ArgumentInfo | - MTLPipelineOption::BufferTypeInfo; + let render_pipeline_state = if program.vertex_shader.arguments.borrow().is_none() + || program.fragment_shader.arguments.borrow().is_none() + { + let reflection_options = + MTLPipelineOption::ArgumentInfo | MTLPipelineOption::BufferTypeInfo; let (render_pipeline_state, reflection) = - self.device - .real_new_render_pipeline_state_with_reflection(&render_pipeline_descriptor, - reflection_options); + self.device.real_new_render_pipeline_state_with_reflection( + &render_pipeline_descriptor, + reflection_options, + ); let mut vertex_arguments = program.vertex_shader.arguments.borrow_mut(); let mut fragment_arguments = program.fragment_shader.arguments.borrow_mut(); if vertex_arguments.is_none() { @@ -1429,17 +1536,20 @@ impl MetalDevice { .expect("Failed to create render pipeline state!") }; - for (vertex_buffer_index, vertex_buffer) in render_state.vertex_array - .vertex_buffers - .borrow() - .iter() - .enumerate() { + for (vertex_buffer_index, vertex_buffer) in render_state + .vertex_array + .vertex_buffers + .borrow() + .iter() + .enumerate() + { let real_index = vertex_buffer_index as u64 + FIRST_VERTEX_BUFFER_INDEX; let buffer = vertex_buffer.allocations.borrow(); - let buffer = buffer.private - .as_ref() - .map(|buffer| buffer.as_ref()) - .expect("Where's the private vertex buffer?"); + let buffer = buffer + .private + .as_ref() + .map(|buffer| buffer.as_ref()) + .expect("Where's the private vertex buffer?"); encoder.set_vertex_buffer(real_index, Some(buffer), 0); } @@ -1450,9 +1560,11 @@ impl MetalDevice { encoder } - fn set_raster_uniforms(&self, - render_command_encoder: &RenderCommandEncoderRef, - render_state: &RenderState) { + fn set_raster_uniforms( + &self, + render_command_encoder: &RenderCommandEncoderRef, + render_state: &RenderState, + ) { let program = match render_state.program { MetalProgram::Raster(ref raster_program) => raster_program, _ => unreachable!(), @@ -1466,28 +1578,38 @@ impl MetalDevice { // Set uniforms. let uniform_buffer = self.create_uniform_buffer(&render_state.uniforms); - for (&(uniform, _), buffer_range) in - render_state.uniforms.iter().zip(uniform_buffer.ranges.iter()) { + for (&(uniform, _), buffer_range) in render_state + .uniforms + .iter() + .zip(uniform_buffer.ranges.iter()) + { self.populate_uniform_indices_if_necessary(uniform, &render_state.program); let indices = uniform.indices.borrow_mut(); let indices = indices.as_ref().unwrap(); let (vertex_indices, fragment_indices) = match indices.0 { - ProgramKind::Raster { ref vertex, ref fragment } => (vertex, fragment), + ProgramKind::Raster { + ref vertex, + ref fragment, + } => (vertex, fragment), _ => unreachable!(), }; if let Some(vertex_index) = *vertex_indices { - self.set_vertex_uniform(vertex_index, - &uniform_buffer.data, - buffer_range, - render_command_encoder); + self.set_vertex_uniform( + vertex_index, + &uniform_buffer.data, + buffer_range, + render_command_encoder, + ); } if let Some(fragment_index) = *fragment_indices { - self.set_fragment_uniform(fragment_index, - &uniform_buffer.data, - buffer_range, - render_command_encoder); + self.set_fragment_uniform( + fragment_index, + &uniform_buffer.data, + buffer_range, + render_command_encoder, + ); } } @@ -1498,19 +1620,22 @@ impl MetalDevice { let indices = texture_param.indices.borrow_mut(); let indices = indices.as_ref().unwrap(); let (vertex_indices, fragment_indices) = match indices.0 { - ProgramKind::Raster { ref vertex, ref fragment } => (vertex, fragment), + ProgramKind::Raster { + ref vertex, + ref fragment, + } => (vertex, fragment), _ => unreachable!(), }; if let Some(vertex_index) = *vertex_indices { - self.encode_vertex_texture_parameter(vertex_index, - render_command_encoder, - texture); + self.encode_vertex_texture_parameter(vertex_index, render_command_encoder, texture); } if let Some(fragment_index) = *fragment_indices { - self.encode_fragment_texture_parameter(fragment_index, - render_command_encoder, - texture); + self.encode_fragment_texture_parameter( + fragment_index, + render_command_encoder, + texture, + ); } } @@ -1521,29 +1646,37 @@ impl MetalDevice { let indices = image_param.indices.borrow_mut(); let indices = indices.as_ref().unwrap(); let (vertex_indices, fragment_indices) = match indices.0 { - ProgramKind::Raster { ref vertex, ref fragment } => (vertex, fragment), + ProgramKind::Raster { + ref vertex, + ref fragment, + } => (vertex, fragment), _ => unreachable!(), }; if let Some(vertex_index) = *vertex_indices { - render_command_encoder.set_vertex_texture(vertex_index.0, - Some(&image.private_texture)); + render_command_encoder + .set_vertex_texture(vertex_index.0, Some(&image.private_texture)); } if let Some(fragment_index) = *fragment_indices { - render_command_encoder.set_fragment_texture(fragment_index.0, - Some(&image.private_texture)); + render_command_encoder + .set_fragment_texture(fragment_index.0, Some(&image.private_texture)); } } // Set storage buffers. for &(storage_buffer_id, storage_buffer_binding) in render_state.storage_buffers { - self.populate_storage_buffer_indices_if_necessary(storage_buffer_id, - &render_state.program); + self.populate_storage_buffer_indices_if_necessary( + storage_buffer_id, + &render_state.program, + ); let indices = storage_buffer_id.indices.borrow_mut(); let indices = indices.as_ref().unwrap(); let (vertex_indices, fragment_indices) = match indices.0 { - ProgramKind::Raster { ref vertex, ref fragment } => (vertex, fragment), + ProgramKind::Raster { + ref vertex, + ref fragment, + } => (vertex, fragment), _ => unreachable!(), }; @@ -1560,13 +1693,18 @@ impl MetalDevice { } } - fn set_compute_uniforms(&self, - compute_command_encoder: &ComputeCommandEncoder, - compute_state: &ComputeState) { + fn set_compute_uniforms( + &self, + compute_command_encoder: &ComputeCommandEncoder, + compute_state: &ComputeState, + ) { // Set uniforms. let uniform_buffer = self.create_uniform_buffer(&compute_state.uniforms); - for (&(uniform, _), buffer_range) in - compute_state.uniforms.iter().zip(uniform_buffer.ranges.iter()) { + for (&(uniform, _), buffer_range) in compute_state + .uniforms + .iter() + .zip(uniform_buffer.ranges.iter()) + { self.populate_uniform_indices_if_necessary(uniform, &compute_state.program); let indices = uniform.indices.borrow_mut(); @@ -1577,10 +1715,12 @@ impl MetalDevice { }; if let Some(indices) = *indices { - self.set_compute_uniform(indices, - &uniform_buffer.data, - buffer_range, - compute_command_encoder); + self.set_compute_uniform( + indices, + &uniform_buffer.data, + buffer_range, + compute_command_encoder, + ); } } @@ -1618,8 +1758,10 @@ impl MetalDevice { // Set storage buffers. for &(storage_buffer_id, storage_buffer_binding) in compute_state.storage_buffers { - self.populate_storage_buffer_indices_if_necessary(storage_buffer_id, - &compute_state.program); + self.populate_storage_buffer_indices_if_necessary( + storage_buffer_id, + &compute_state.program, + ); let indices = storage_buffer_id.indices.borrow_mut(); let indices = indices.as_ref().unwrap(); @@ -1641,49 +1783,93 @@ impl MetalDevice { for &(_, uniform_data) in uniforms.iter() { let start_index = uniform_buffer_data.len(); match uniform_data { - UniformData::Float(value) => { - uniform_buffer_data.write_f32::(value).unwrap() - } + 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(); + 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() + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); } } let end_index = uniform_buffer_data.len(); @@ -1699,73 +1885,91 @@ impl MetalDevice { } } - fn set_vertex_uniform(&self, - argument_index: MetalUniformIndex, - buffer: &[u8], - buffer_range: &Range, - render_command_encoder: &RenderCommandEncoderRef) { + fn set_vertex_uniform( + &self, + argument_index: MetalUniformIndex, + buffer: &[u8], + buffer_range: &Range, + render_command_encoder: &RenderCommandEncoderRef, + ) { render_command_encoder.set_vertex_bytes( argument_index.0, (buffer_range.end - buffer_range.start) as u64, - &buffer[buffer_range.start as usize] as *const u8 as *const _) + &buffer[buffer_range.start as usize] as *const u8 as *const _, + ) } - fn set_fragment_uniform(&self, - argument_index: MetalUniformIndex, - buffer: &[u8], - buffer_range: &Range, - render_command_encoder: &RenderCommandEncoderRef) { + fn set_fragment_uniform( + &self, + argument_index: MetalUniformIndex, + buffer: &[u8], + buffer_range: &Range, + render_command_encoder: &RenderCommandEncoderRef, + ) { render_command_encoder.set_fragment_bytes( argument_index.0, (buffer_range.end - buffer_range.start) as u64, - &buffer[buffer_range.start as usize] as *const u8 as *const _) + &buffer[buffer_range.start as usize] as *const u8 as *const _, + ) } - fn set_compute_uniform(&self, - argument_index: MetalUniformIndex, - buffer: &[u8], - buffer_range: &Range, - compute_command_encoder: &ComputeCommandEncoder) { + fn set_compute_uniform( + &self, + argument_index: MetalUniformIndex, + buffer: &[u8], + buffer_range: &Range, + compute_command_encoder: &ComputeCommandEncoder, + ) { compute_command_encoder.set_bytes( argument_index.0, (buffer_range.end - buffer_range.start) as u64, - &buffer[buffer_range.start as usize] as *const u8 as *const _) + &buffer[buffer_range.start as usize] as *const u8 as *const _, + ) } - fn encode_vertex_texture_parameter(&self, - argument_index: MetalTextureIndex, - render_command_encoder: &RenderCommandEncoderRef, - texture: &MetalTexture) { - render_command_encoder.set_vertex_texture(argument_index.main, - Some(&texture.private_texture)); + fn encode_vertex_texture_parameter( + &self, + argument_index: MetalTextureIndex, + render_command_encoder: &RenderCommandEncoderRef, + texture: &MetalTexture, + ) { + render_command_encoder + .set_vertex_texture(argument_index.main, Some(&texture.private_texture)); let sampler = &self.samplers[texture.sampling_flags.get().bits() as usize]; render_command_encoder.set_vertex_sampler_state(argument_index.sampler, Some(sampler)); } - fn encode_fragment_texture_parameter(&self, - argument_index: MetalTextureIndex, - render_command_encoder: &RenderCommandEncoderRef, - texture: &MetalTexture) { - render_command_encoder.set_fragment_texture(argument_index.main, - Some(&texture.private_texture)); + fn encode_fragment_texture_parameter( + &self, + argument_index: MetalTextureIndex, + render_command_encoder: &RenderCommandEncoderRef, + texture: &MetalTexture, + ) { + render_command_encoder + .set_fragment_texture(argument_index.main, Some(&texture.private_texture)); let sampler = &self.samplers[texture.sampling_flags.get().bits() as usize]; render_command_encoder.set_fragment_sampler_state(argument_index.sampler, Some(sampler)); } - fn encode_compute_texture_parameter(&self, - argument_index: MetalTextureIndex, - compute_command_encoder: &ComputeCommandEncoder, - texture: &MetalTexture) { + fn encode_compute_texture_parameter( + &self, + argument_index: MetalTextureIndex, + compute_command_encoder: &ComputeCommandEncoder, + texture: &MetalTexture, + ) { compute_command_encoder.set_texture(argument_index.main, Some(&texture.private_texture)); let sampler = &self.samplers[texture.sampling_flags.get().bits() as usize]; compute_command_encoder.set_sampler_state(argument_index.sampler, Some(sampler)); } fn prepare_pipeline_color_attachment_for_render( - &self, - pipeline_color_attachment: &RenderPipelineColorAttachmentDescriptorRef, - render_state: &RenderState) { - let pixel_format = self.render_target_color_texture(&render_state.target).pixel_format(); + &self, + pipeline_color_attachment: &RenderPipelineColorAttachmentDescriptorRef, + render_state: &RenderState, + ) { + let pixel_format = self + .render_target_color_texture(&render_state.target) + .pixel_format(); pipeline_color_attachment.set_pixel_format(pixel_format); match render_state.options.blend { @@ -1773,14 +1977,16 @@ impl MetalDevice { Some(ref blend) => { pipeline_color_attachment.set_blending_enabled(true); - pipeline_color_attachment.set_source_rgb_blend_factor( - blend.src_rgb_factor.to_metal_blend_factor()); + pipeline_color_attachment + .set_source_rgb_blend_factor(blend.src_rgb_factor.to_metal_blend_factor()); pipeline_color_attachment.set_destination_rgb_blend_factor( - blend.dest_rgb_factor.to_metal_blend_factor()); - pipeline_color_attachment.set_source_alpha_blend_factor( - blend.src_alpha_factor.to_metal_blend_factor()); + blend.dest_rgb_factor.to_metal_blend_factor(), + ); + pipeline_color_attachment + .set_source_alpha_blend_factor(blend.src_alpha_factor.to_metal_blend_factor()); pipeline_color_attachment.set_destination_alpha_blend_factor( - blend.dest_alpha_factor.to_metal_blend_factor()); + blend.dest_alpha_factor.to_metal_blend_factor(), + ); let blend_op = blend.op.to_metal_blend_op(); pipeline_color_attachment.set_rgb_blend_operation(blend_op); @@ -1795,18 +2001,25 @@ impl MetalDevice { } } - fn create_render_pass_descriptor(&self, render_state: &RenderState) - -> RenderPassDescriptor { + fn create_render_pass_descriptor( + &self, + render_state: &RenderState, + ) -> RenderPassDescriptor { let render_pass_descriptor = RenderPassDescriptor::new_retained(); - let color_attachment = render_pass_descriptor.color_attachments().object_at(0).unwrap(); + let color_attachment = render_pass_descriptor + .color_attachments() + .object_at(0) + .unwrap(); color_attachment.set_texture(Some(&self.render_target_color_texture(render_state.target))); match render_state.options.clear_ops.color { Some(color) => { - let color = MTLClearColor::new(color.r() as f64, - color.g() as f64, - color.b() as f64, - color.a() as f64); + let color = MTLClearColor::new( + color.r() as f64, + color.g() as f64, + color.b() as f64, + color.a() as f64, + ); color_attachment.set_clear_color(color); color_attachment.set_load_action(MTLLoadAction::Clear); } @@ -1843,9 +2056,11 @@ impl MetalDevice { render_pass_descriptor } - fn set_depth_stencil_state(&self, - encoder: &RenderCommandEncoderRef, - render_state: &RenderState) { + fn set_depth_stencil_state( + &self, + encoder: &RenderCommandEncoderRef, + render_state: &RenderState, + ) { let depth_stencil_descriptor = DepthStencilDescriptor::new(); match render_state.options.depth { @@ -1884,7 +2099,9 @@ impl MetalDevice { } } - let depth_stencil_state = self.device.new_depth_stencil_state(&depth_stencil_descriptor); + let depth_stencil_state = self + .device + .new_depth_stencil_state(&depth_stencil_descriptor); encoder.set_depth_stencil_state(&depth_stencil_state); } @@ -1965,9 +2182,7 @@ impl IntoMetalDevice for NativeMetalDevice { impl<'a> IntoMetalDevice for &'a DeviceRef { #[inline] fn into_metal_device(self) -> NativeMetalDevice { - unsafe { - msg_send![self, retain] - } + unsafe { msg_send![self, retain] } } } @@ -2070,7 +2285,11 @@ trait ComputeDimensionsExt { impl ComputeDimensionsExt for ComputeDimensions { #[inline] fn to_metal_size(self) -> MTLSize { - MTLSize { width: self.x as u64, height: self.y as u64, depth: self.z as u64 } + MTLSize { + width: self.x as u64, + height: self.y as u64, + depth: self.z as u64, + } } } @@ -2190,8 +2409,9 @@ impl TextureFormatExt for TextureFormat { // Synchronization helpers -fn try_recv_timer_query_with_guard(guard: &mut MutexGuard) - -> Option { +fn try_recv_timer_query_with_guard( + guard: &mut MutexGuard, +) -> Option { match (guard.start_time, guard.end_time) { (Some(start_time), Some(end_time)) => Some(end_time - start_time), _ => None, @@ -2201,9 +2421,20 @@ fn try_recv_timer_query_with_guard(guard: &mut MutexGuard) impl MetalTextureDataReceiver { fn download(&self) { let (origin, size) = (self.0.viewport.origin(), self.0.viewport.size()); - let metal_origin = MTLOrigin { x: origin.x() as u64, y: origin.y() as u64, z: 0 }; - let metal_size = MTLSize { width: size.x() as u64, height: size.y() as u64, depth: 1 }; - let metal_region = MTLRegion { origin: metal_origin, size: metal_size }; + let metal_origin = MTLOrigin { + x: origin.x() as u64, + y: origin.y() as u64, + z: 0, + }; + let metal_size = MTLSize { + width: size.x() as u64, + height: size.y() as u64, + depth: 1, + }; + let metal_region = MTLRegion { + origin: metal_origin, + size: metal_size, + }; let format = TextureFormat::from_metal_pixel_format(self.0.texture.pixel_format()); let format = format.expect("Unexpected framebuffer texture format!"); @@ -2213,30 +2444,36 @@ impl MetalTextureDataReceiver { let channels = format.channels(); let stride = size.x() as usize * channels; let mut pixels = vec![0; stride * size.y() as usize]; - self.0.texture.get_bytes(pixels.as_mut_ptr() as *mut _, - metal_region, - 0, - stride as u64); + self.0.texture.get_bytes( + pixels.as_mut_ptr() as *mut _, + metal_region, + 0, + stride as u64, + ); TextureData::U8(pixels) } TextureFormat::R16F | TextureFormat::RGBA16F => { let channels = format.channels(); let stride = size.x() as usize * channels; let mut pixels = vec![f16::default(); stride * size.y() as usize]; - self.0.texture.get_bytes(pixels.as_mut_ptr() as *mut _, - metal_region, - 0, - stride as u64 * 2); + self.0.texture.get_bytes( + pixels.as_mut_ptr() as *mut _, + metal_region, + 0, + stride as u64 * 2, + ); TextureData::F16(pixels) } TextureFormat::RGBA32F => { let channels = format.channels(); let stride = size.x() as usize * channels; let mut pixels = vec![0.0; stride * size.y() as usize]; - self.0.texture.get_bytes(pixels.as_mut_ptr() as *mut _, - metal_region, - 0, - stride as u64 * 4); + self.0.texture.get_bytes( + pixels.as_mut_ptr() as *mut _, + metal_region, + 0, + stride as u64 * 4, + ); TextureData::F32(pixels) } }; @@ -2252,8 +2489,10 @@ impl MetalBufferDataReceiver { let staging_buffer_contents = self.0.staging_buffer.contents() as *const u8; let staging_buffer_length = self.0.staging_buffer.length(); unsafe { - let contents = slice::from_raw_parts(staging_buffer_contents, - staging_buffer_length.try_into().unwrap()); + let contents = slice::from_raw_parts( + staging_buffer_contents, + staging_buffer_length.try_into().unwrap(), + ); let mut guard = self.0.mutex.lock().unwrap(); *guard = MetalDataReceiverState::Downloaded(contents.to_vec()); self.0.cond.notify_all(); @@ -2263,9 +2502,7 @@ impl MetalBufferDataReceiver { fn try_recv_data_with_guard(guard: &mut MutexGuard>) -> Option { match **guard { - MetalDataReceiverState::Pending | MetalDataReceiverState::Finished => { - return None - } + MetalDataReceiverState::Pending | MetalDataReceiverState::Finished => return None, MetalDataReceiverState::Downloaded(_) => {} } match mem::replace(&mut **guard, MetalDataReceiverState::Finished) { @@ -2319,16 +2556,17 @@ impl Drop for SharedEvent { } impl SharedEvent { - fn notify_listener_at_value(&self, - listener: &SharedEventListener, - value: u64, - block: RcBlock<(*mut Object, u64), ()>) { + fn notify_listener_at_value( + &self, + listener: &SharedEventListener, + value: u64, + block: RcBlock<(*mut Object, u64), ()>, + ) { unsafe { // If the block doesn't have a signature, this segfaults. - let block = &*block as - *const Block<(*mut Object, u64), ()> as - *mut Block<(*mut Object, u64), ()> as - *mut BlockBase<(*mut Object, u64), ()>; + let block = &*block as *const Block<(*mut Object, u64), ()> + as *mut Block<(*mut Object, u64), ()> + as *mut BlockBase<(*mut Object, u64), ()>; (*block).flags |= BLOCK_HAS_SIGNATURE | BLOCK_HAS_COPY_DISPOSE; (*block).extra = &BLOCK_EXTRA; let () = msg_send![self.0, notifyListener:listener.0 atValue:value block:block]; @@ -2416,8 +2654,10 @@ trait CommandBufferExt { fn encode_signal_event(&self, event: &SharedEvent, value: u64); fn add_completed_handler(&self, block: RcBlock<(*mut Object,), ()>); // Just like `new_render_command_encoder`, but returns an owned version. - fn new_render_command_encoder_retained(&self, render_pass_descriptor: &RenderPassDescriptorRef) - -> RenderCommandEncoder; + fn new_render_command_encoder_retained( + &self, + render_pass_descriptor: &RenderPassDescriptorRef, + ) -> RenderCommandEncoder; // Just like `new_blit_command_encoder`, but doesn't leak. fn real_new_blit_command_encoder(&self) -> BlitCommandEncoder; // Just like `new_compute_command_encoder`, but doesn't leak. @@ -2426,22 +2666,19 @@ trait CommandBufferExt { impl CommandBufferExt for CommandBuffer { fn encode_signal_event(&self, event: &SharedEvent, value: u64) { - unsafe { - msg_send![self.as_ptr(), encodeSignalEvent:event.0 value:value] - } + unsafe { msg_send![self.as_ptr(), encodeSignalEvent:event.0 value:value] } } fn add_completed_handler(&self, block: RcBlock<(*mut Object,), ()>) { - unsafe { - msg_send![self.as_ptr(), addCompletedHandler:&*block] - } + unsafe { msg_send![self.as_ptr(), addCompletedHandler:&*block] } } - fn new_render_command_encoder_retained(&self, render_pass_descriptor: &RenderPassDescriptorRef) - -> RenderCommandEncoder { + fn new_render_command_encoder_retained( + &self, + render_pass_descriptor: &RenderPassDescriptorRef, + ) -> RenderCommandEncoder { unsafe { - let encoder: id = - msg_send![self.as_ptr(), + let encoder: id = msg_send![self.as_ptr(), renderCommandEncoderWithDescriptor:render_pass_descriptor.as_ptr()]; RenderCommandEncoder::from_ptr(msg_send![encoder, retain]) } @@ -2479,39 +2716,42 @@ impl CommandQueueExt for CommandQueue { trait DeviceExt { // `new_render_pipeline_state_with_reflection()` in `metal-rs` doesn't correctly initialize the // `reflection` argument. This is a better definition. - fn real_new_render_pipeline_state_with_reflection(&self, - descriptor: &RenderPipelineDescriptor, - options: MTLPipelineOption) - -> (RenderPipelineState, - RenderPipelineReflection); + fn real_new_render_pipeline_state_with_reflection( + &self, + descriptor: &RenderPipelineDescriptor, + options: MTLPipelineOption, + ) -> (RenderPipelineState, RenderPipelineReflection); fn new_shared_event(&self) -> SharedEvent; fn new_fence(&self) -> Fence; } impl DeviceExt for metal::Device { - fn real_new_render_pipeline_state_with_reflection(&self, - descriptor: &RenderPipelineDescriptor, - options: MTLPipelineOption) - -> (RenderPipelineState, - RenderPipelineReflection) { + fn real_new_render_pipeline_state_with_reflection( + &self, + descriptor: &RenderPipelineDescriptor, + options: MTLPipelineOption, + ) -> (RenderPipelineState, RenderPipelineReflection) { unsafe { let mut reflection_ptr: *mut MTLRenderPipelineReflection = ptr::null_mut(); let mut error_ptr: *mut Object = ptr::null_mut(); - let render_pipeline_state_ptr: *mut MTLRenderPipelineState = - msg_send![self.as_ptr(), + let render_pipeline_state_ptr: *mut MTLRenderPipelineState = msg_send![self.as_ptr(), newRenderPipelineStateWithDescriptor:descriptor.as_ptr() options:options reflection:&mut reflection_ptr error:&mut error_ptr]; if !error_ptr.is_null() { let description: CFStringRef = msg_send![error_ptr, description]; - panic!("Render pipeline state construction failed: {}", - CFString::wrap_under_get_rule(description).to_string()); + panic!( + "Render pipeline state construction failed: {}", + CFString::wrap_under_get_rule(description).to_string() + ); } assert!(!render_pipeline_state_ptr.is_null()); assert!(!reflection_ptr.is_null()); - (RenderPipelineState::from_ptr(render_pipeline_state_ptr), - RenderPipelineReflection::from_ptr(msg_send![reflection_ptr, retain])) + ( + RenderPipelineState::from_ptr(render_pipeline_state_ptr), + RenderPipelineReflection::from_ptr(msg_send![reflection_ptr, retain]), + ) } } @@ -2527,26 +2767,30 @@ impl DeviceExt for metal::Device { trait FunctionExt { // `vertex_attributes()` in `metal-rs` segfaults! This is a better definition. fn real_vertex_attributes(&self) -> VertexAttributeArray; - fn new_argument_encoder_with_reflection(&self, buffer_index: u64) - -> (ArgumentEncoder, Argument); + fn new_argument_encoder_with_reflection( + &self, + buffer_index: u64, + ) -> (ArgumentEncoder, Argument); } impl FunctionExt for Function { fn real_vertex_attributes(&self) -> VertexAttributeArray { - unsafe { - VertexAttributeArray::from_ptr(msg_send![(*self).as_ptr(), vertexAttributes]) - } + unsafe { VertexAttributeArray::from_ptr(msg_send![(*self).as_ptr(), vertexAttributes]) } } - fn new_argument_encoder_with_reflection(&self, buffer_index: u64) - -> (ArgumentEncoder, Argument) { + fn new_argument_encoder_with_reflection( + &self, + buffer_index: u64, + ) -> (ArgumentEncoder, Argument) { unsafe { let mut reflection = ptr::null_mut(); - let encoder: *mut MTLArgumentEncoder = - msg_send![self.as_ptr(), newArgumentEncoderWithBufferIndex:buffer_index + let encoder: *mut MTLArgumentEncoder = msg_send![self.as_ptr(), newArgumentEncoderWithBufferIndex:buffer_index reflection:&mut reflection]; let () = msg_send![reflection, retain]; - (ArgumentEncoder::from_ptr(encoder), Argument::from_ptr(reflection)) + ( + ArgumentEncoder::from_ptr(encoder), + Argument::from_ptr(reflection), + ) } } } @@ -2609,9 +2853,7 @@ impl RenderCommandEncoderExt for RenderCommandEncoderRef { } fn wait_for_fence_before_stages(&self, fence: &Fence, stages: MTLRenderStage) { - unsafe { - msg_send![self.as_ptr(), waitForFence:fence.0 beforeStages:stages] - } + unsafe { msg_send![self.as_ptr(), waitForFence:fence.0 beforeStages:stages] } } } @@ -2688,31 +2930,31 @@ impl Retain for VertexDescriptorRef { // Extra block stuff not supported by `block` const BLOCK_HAS_COPY_DISPOSE: i32 = 0x02000000; -const BLOCK_HAS_SIGNATURE: i32 = 0x40000000; +const BLOCK_HAS_SIGNATURE: i32 = 0x40000000; #[repr(C)] struct BlockBase { - isa: *const Class, // 0x00 - flags: i32, // 0x08 - _reserved: i32, // 0x0c - invoke: unsafe extern fn(*mut Block, ...) -> R, // 0x10 - extra: *const BlockExtra, // 0x18 + isa: *const Class, // 0x00 + flags: i32, // 0x08 + _reserved: i32, // 0x0c + invoke: unsafe extern "C" fn(*mut Block, ...) -> R, // 0x10 + extra: *const BlockExtra, // 0x18 } type BlockExtraDtor = extern "C" fn(*mut BlockBase); #[repr(C)] struct BlockExtra { - unknown0: *mut i32, // 0x00 - unknown1: *mut i32, // 0x08 - unknown2: *mut i32, // 0x10 - dtor: BlockExtraDtor, // 0x18 - signature: *const *const i8, // 0x20 + unknown0: *mut i32, // 0x00 + unknown1: *mut i32, // 0x08 + unknown2: *mut i32, // 0x10 + dtor: BlockExtraDtor, // 0x18 + signature: *const *const i8, // 0x20 } // TODO(pcwalton): These should go upstream to `core-foundation-rs`. #[link(name = "IOSurface", kind = "framework")] -extern { +extern "C" { fn IOSurfaceGetWidth(buffer: IOSurfaceRef) -> size_t; fn IOSurfaceGetHeight(buffer: IOSurfaceRef) -> size_t; } diff --git a/renderer/src/allocator.rs b/renderer/src/allocator.rs index 8cf9408e..4d171255 100644 --- a/renderer/src/allocator.rs +++ b/renderer/src/allocator.rs @@ -12,7 +12,7 @@ use crate::gpu_data::{TextureLocation, TexturePageId}; use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2f, vec2i}; +use pathfinder_geometry::vector::{vec2f, vec2i, Vector2F, Vector2I}; const ATLAS_TEXTURE_LENGTH: u32 = 1024; @@ -64,9 +64,10 @@ impl TextureAllocator { 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 { + 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); } @@ -74,19 +75,17 @@ impl TextureAllocator { let mut first_free_page_index = self.pages.len(); for (page_index, page) in self.pages.iter_mut().enumerate() { match *page { - Some(ref mut page) => { - 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 - }; - } + Some(ref mut page) => 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, + }; } } - } + }, None => first_free_page_index = first_free_page_index.min(page_index), } } @@ -94,7 +93,9 @@ impl TextureAllocator { // Add a new atlas. let page = self.get_first_free_page_id(); let mut allocator = TextureAtlasAllocator::new(); - let rect = allocator.allocate(requested_size).expect("Allocation failed!"); + let rect = allocator + .allocate(requested_size) + .expect("Allocation failed!"); while (page.0 as usize) >= self.pages.len() { self.pages.push(None); } @@ -130,9 +131,10 @@ impl TextureAllocator { pub fn free(&mut self, location: TextureLocation) { //println!("free({:?})", location); match self.pages[location.page.0 as usize] - .as_mut() - .expect("Texture page is not allocated!") - .allocator { + .as_mut() + .expect("Texture page is not allocated!") + .allocator + { TexturePageAllocator::Image { size } => { debug_assert_eq!(location.rect, RectI::new(Vector2I::default(), size)); } @@ -151,7 +153,11 @@ impl TextureAllocator { } pub fn page_size(&self, page_id: TexturePageId) -> Vector2I { - match self.pages[page_id.0 as usize].as_ref().expect("No such texture page!").allocator { + match self.pages[page_id.0 as usize] + .as_ref() + .expect("No such texture page!") + .allocator + { TexturePageAllocator::Atlas(ref atlas) => Vector2I::splat(atlas.size as i32), TexturePageAllocator::Image { size, .. } => size, } @@ -162,7 +168,10 @@ impl TextureAllocator { } pub fn page_is_new(&self, page_id: TexturePageId) -> bool { - self.pages[page_id.0 as usize].as_ref().expect("No such texture page!").is_new + self.pages[page_id.0 as usize] + .as_ref() + .expect("No such texture page!") + .is_new } pub fn mark_all_pages_as_allocated(&mut self) { @@ -178,7 +187,10 @@ impl TextureAllocator { while first_index < self.pages.len() && self.pages[first_index].is_none() { first_index += 1; } - TexturePageIter { allocator: self, next_index: first_index } + TexturePageIter { + allocator: self, + next_index: first_index, + } } } @@ -190,20 +202,29 @@ impl TextureAtlasAllocator { #[inline] fn with_length(length: u32) -> TextureAtlasAllocator { - TextureAtlasAllocator { root: TreeNode::EmptyLeaf, size: length } + 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) + self.root + .allocate(Vector2I::default(), self.size, requested_length) } #[inline] fn free(&mut self, rect: RectI) { let requested_length = rect.width() as u32; - self.root.free(Vector2I::default(), self.size, rect.origin(), requested_length) + self.root.free( + Vector2I::default(), + self.size, + rect.origin(), + requested_length, + ) } #[inline] @@ -218,8 +239,12 @@ impl TextureAtlasAllocator { 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 { + fn allocate( + &mut self, + this_origin: Vector2I, + this_size: u32, + requested_size: u32, + ) -> Option { if let TreeNode::FullLeaf = *self { // No room here. return None; @@ -253,19 +278,23 @@ impl TreeNode { 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) { + 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) { + 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) { + if let Some(origin) = + kids[3].allocate(this_origin + kid_size as i32, kid_size, requested_size) + { return Some(origin); } @@ -277,11 +306,13 @@ impl TreeNode { } #[allow(dead_code)] - fn free(&mut self, - this_origin: Vector2I, - this_size: u32, - requested_origin: Vector2I, - requested_size: u32) { + 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; @@ -324,11 +355,9 @@ impl TreeNode { fn merge_if_necessary(&mut self) { match *self { TreeNode::Parent(ref mut kids) => { - if kids.iter().all(|kid| { - match **kid { - TreeNode::EmptyLeaf => true, - _ => false, - } + if kids.iter().all(|kid| match **kid { + TreeNode::EmptyLeaf => true, + _ => false, }) { *self = TreeNode::EmptyLeaf; } @@ -353,8 +382,9 @@ impl<'a> Iterator for TexturePageIter<'a> { }; loop { self.next_index += 1; - if self.next_index >= self.allocator.pages.len() || - self.allocator.pages[self.next_index as usize].is_some() { + if self.next_index >= self.allocator.pages.len() + || self.allocator.pages[self.next_index as usize].is_some() + { break; } } @@ -372,8 +402,9 @@ mod test { #[test] fn test_allocation_and_freeing() { - quickcheck::quickcheck(prop_allocation_and_freeing_work as - fn(u32, Vec<(u32, u32)>) -> bool); + 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); diff --git a/renderer/src/builder.rs b/renderer/src/builder.rs index 0a391cc2..ec465ded 100644 --- a/renderer/src/builder.rs +++ b/renderer/src/builder.rs @@ -14,7 +14,7 @@ use crate::concurrent::executor::Executor; use crate::gpu::blend::BlendModeExt; use crate::gpu::options::RendererLevel; use crate::gpu_data::{AlphaTileId, BackdropInfoD3D11, Clip, ClippedPathInfo, DiceMetadataD3D11}; -use crate::gpu_data::{DrawTileBatch, DrawTileBatchD3D9, DrawTileBatchD3D11, Fill, GlobalPathId}; +use crate::gpu_data::{DrawTileBatch, DrawTileBatchD3D11, DrawTileBatchD3D9, Fill, GlobalPathId}; use crate::gpu_data::{PathBatchIndex, PathSource, PrepareTilesInfoD3D11, PropagateMetadataD3D11}; use crate::gpu_data::{RenderCommand, SegmentIndicesD3D11, SegmentsD3D11, TileBatchDataD3D11}; use crate::gpu_data::{TileBatchId, TileBatchTexture, TileObjectPrimitive, TilePathInfoD3D11}; @@ -24,7 +24,7 @@ use crate::scene::{ClipPathId, DisplayItem, DrawPath, DrawPathId, LastSceneInfo, use crate::scene::{Scene, SceneSink}; use crate::tile_map::DenseTileMap; use crate::tiler::Tiler; -use crate::tiles::{self, DrawTilingPathInfo, TILE_HEIGHT, TILE_WIDTH, TilingPathInfo}; +use crate::tiles::{self, DrawTilingPathInfo, TilingPathInfo, TILE_HEIGHT, TILE_WIDTH}; use fxhash::FxHashMap; use instant::Instant; use pathfinder_content::effects::{BlendMode, Filter}; @@ -33,7 +33,7 @@ use pathfinder_content::outline::{Outline, PointFlags}; use pathfinder_geometry::line_segment::{LineSegment2F, LineSegmentU16}; use pathfinder_geometry::rect::{RectF, RectI}; use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::vector::{Vector2I, vec2i}; +use pathfinder_geometry::vector::{vec2i, Vector2I}; use pathfinder_gpu::TextureSamplingFlags; use pathfinder_simd::default::F32x4; use std::borrow::Cow; @@ -45,7 +45,7 @@ pub(crate) const ALPHA_TILE_LEVEL_COUNT: usize = 2; pub(crate) const ALPHA_TILES_PER_LEVEL: usize = 1 << (32 - ALPHA_TILE_LEVEL_COUNT + 1); const CURVE_IS_QUADRATIC: u32 = 0x80000000; -const CURVE_IS_CUBIC: u32 = 0x40000000; +const CURVE_IS_CUBIC: u32 = 0x40000000; const MAX_CLIP_BATCHES: u32 = 32; @@ -77,8 +77,11 @@ struct BuiltDrawPath { } impl BuiltDrawPath { - fn new(built_path: BuiltPath, path_object: &DrawPath, paint_metadata: &PaintMetadata) - -> BuiltDrawPath { + fn new( + built_path: BuiltPath, + path_object: &DrawPath, + paint_metadata: &PaintMetadata, + ) -> BuiltDrawPath { let blend_mode = path_object.blend_mode(); let occludes = paint_metadata.is_opaque && blend_mode.occludes_backdrop(); BuiltDrawPath { @@ -133,10 +136,11 @@ pub(crate) struct Occluder { } impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { - pub(crate) fn new(scene: &'a mut Scene, - built_options: &'b PreparedBuildOptions, - sink: &'c mut SceneSink<'d>) - -> SceneBuilder<'a, 'b, 'c, 'd> { + pub(crate) fn new( + scene: &'a mut Scene, + built_options: &'b PreparedBuildOptions, + sink: &'c mut SceneSink<'d>, + ) -> SceneBuilder<'a, 'b, 'c, 'd> { SceneBuilder { scene, built_options, @@ -145,7 +149,10 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { } } - pub fn build(&mut self, executor: &E) where E: Executor { + pub fn build(&mut self, executor: &E) + where + E: Executor, + { let start_time = Instant::now(); // Send the start rendering command. @@ -167,14 +174,16 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { let render_transform = match self.built_options.transform { PreparedRenderTransform::Transform2D(transform) => transform.inverse(), - _ => Transform2F::default() + _ => Transform2F::default(), }; // Build paint data. let PaintInfo { render_commands, paint_metadata, - } = self.scene.build_paint_info(&mut self.sink.paint_texture_manager, render_transform); + } = self + .scene + .build_paint_info(&mut self.sink.paint_texture_manager, render_transform); for render_command in render_commands { self.sink.listener.send(render_command); } @@ -189,11 +198,14 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { // TODO(pcwalton): Do this earlier? let scene_is_dirty = match (&prepare_mode, &self.sink.last_scene) { (&PrepareMode::GPU { .. }, &None) => true, - (&PrepareMode::GPU { .. }, &Some(LastSceneInfo { - scene_id: ref last_scene_id, - scene_epoch: ref last_scene_epoch, - .. - })) => *last_scene_id != self.scene.id() || *last_scene_epoch != self.scene.epoch(), + ( + &PrepareMode::GPU { .. }, + &Some(LastSceneInfo { + scene_id: ref last_scene_id, + scene_epoch: ref last_scene_epoch, + .. + }), + ) => *last_scene_id != self.scene.id() || *last_scene_epoch != self.scene.epoch(), _ => false, }; @@ -214,15 +226,20 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { self.finish_building(&paint_metadata, built_paths, &prepare_mode); let cpu_build_time = Instant::now() - start_time; - self.sink.listener.send(RenderCommand::Finish { cpu_build_time }); + self.sink + .listener + .send(RenderCommand::Finish { cpu_build_time }); } - fn build_paths_on_cpu(&mut self, - executor: &E, - paint_metadata: &[PaintMetadata], - prepare_mode: &PrepareMode) - -> BuiltPaths - where E: Executor { + fn build_paths_on_cpu( + &mut self, + executor: &E, + paint_metadata: &[PaintMetadata], + prepare_mode: &PrepareMode, + ) -> BuiltPaths + where + E: Executor, + { let clip_path_count = self.scene.clip_paths().len(); let draw_path_count = self.scene.draw_paths().len(); let effective_view_box = self.scene.effective_view_box(self.built_options); @@ -251,23 +268,33 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { }) }); - BuiltPaths { draw: built_draw_paths } + BuiltPaths { + draw: built_draw_paths, + } } fn build_clip_path_on_cpu(&self, params: PathBuildParams) -> BuiltPath { - let PathBuildParams { path_id, view_box, built_options, scene, prepare_mode } = params; + let PathBuildParams { + path_id, + view_box, + built_options, + scene, + prepare_mode, + } = params; let path_object = &scene.get_clip_path(path_id.to_clip_path_id()); let outline = scene.apply_render_options(path_object.outline(), built_options); - let mut tiler = Tiler::new(self, - path_id, - &outline, - path_object.fill_rule(), - view_box, - &prepare_mode, - path_object.clip_path(), - &[], - TilingPathInfo::Clip); + let mut tiler = Tiler::new( + self, + path_id, + &outline, + path_object.fill_rule(), + view_box, + &prepare_mode, + path_object.clip_path(), + &[], + TilingPathInfo::Clip, + ); tiler.generate_tiles(); self.send_fills(tiler.object_builder.fills); @@ -276,13 +303,14 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { fn build_draw_path_on_cpu(&self, params: DrawPathBuildParams) -> BuiltDrawPath { let DrawPathBuildParams { - path_build_params: PathBuildParams { - path_id, - view_box, - built_options, - prepare_mode, - scene, - }, + path_build_params: + PathBuildParams { + path_id, + view_box, + built_options, + prepare_mode, + scene, + }, paint_metadata, built_clip_paths, } = params; @@ -293,19 +321,21 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { let paint_id = path_object.paint(); let paint_metadata = &paint_metadata[paint_id.0 as usize]; - let mut tiler = Tiler::new(self, - path_id, - &outline, - path_object.fill_rule(), - view_box, - &prepare_mode, - path_object.clip_path(), - &built_clip_paths, - TilingPathInfo::Draw(DrawTilingPathInfo { - paint_id, - blend_mode: path_object.blend_mode(), - fill_rule: path_object.fill_rule(), - })); + let mut tiler = Tiler::new( + self, + path_id, + &outline, + path_object.fill_rule(), + view_box, + &prepare_mode, + path_object.clip_path(), + &built_clip_paths, + TilingPathInfo::Draw(DrawTilingPathInfo { + paint_id, + blend_mode: path_object.blend_mode(), + fill_rule: path_object.fill_rule(), + }), + ); tiler.generate_tiles(); self.send_fills(tiler.object_builder.fills); @@ -319,22 +349,23 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { } } - fn build_tile_batches(&mut self, - paint_metadata: &[PaintMetadata], - prepare_mode: &PrepareMode, - built_paths: Option) { + fn build_tile_batches( + &mut self, + paint_metadata: &[PaintMetadata], + prepare_mode: &PrepareMode, + built_paths: Option, + ) { let mut tile_batch_builder = TileBatchBuilder::new(built_paths); // Prepare display items. for display_item in self.scene.display_list() { match *display_item { - DisplayItem::PushRenderTarget(render_target_id) => { - tile_batch_builder.draw_commands - .push(RenderCommand::PushRenderTarget(render_target_id)) - } - DisplayItem::PopRenderTarget => { - tile_batch_builder.draw_commands.push(RenderCommand::PopRenderTarget) - } + DisplayItem::PushRenderTarget(render_target_id) => tile_batch_builder + .draw_commands + .push(RenderCommand::PushRenderTarget(render_target_id)), + DisplayItem::PopRenderTarget => tile_batch_builder + .draw_commands + .push(RenderCommand::PopRenderTarget), DisplayItem::DrawPaths(ref path_id_range) => { tile_batch_builder.build_tile_batches_for_draw_path_display_item( &self.scene, @@ -342,7 +373,8 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { self.built_options, path_id_range.start..path_id_range.end, paint_metadata, - prepare_mode); + prepare_mode, + ); } } } @@ -351,10 +383,12 @@ impl<'a, 'b, 'c, 'd> SceneBuilder<'a, 'b, 'c, 'd> { tile_batch_builder.send_to(&self.sink); } - fn finish_building(&mut self, - paint_metadata: &[PaintMetadata], - built_paths: Option, - prepare_mode: &PrepareMode) { + fn finish_building( + &mut self, + paint_metadata: &[PaintMetadata], + built_paths: Option, + prepare_mode: &PrepareMode, + ) { match self.sink.renderer_level { RendererLevel::D3D9 => self.sink.listener.send(RenderCommand::FlushFillsD3D9), RendererLevel::D3D11 => {} @@ -406,14 +440,15 @@ struct DrawPathBuildParams<'a> { } impl BuiltPath { - fn new(path_id: PathId, - path_bounds: RectF, - view_box_bounds: RectF, - fill_rule: FillRule, - prepare_mode: &PrepareMode, - clip_path_id: Option, - tiling_path_info: &TilingPathInfo) - -> BuiltPath { + fn new( + path_id: PathId, + path_bounds: RectF, + view_box_bounds: RectF, + fill_rule: FillRule, + prepare_mode: &PrepareMode, + clip_path_id: Option, + tiling_path_info: &TilingPathInfo, + ) -> BuiltPath { let paint_id = match *tiling_path_info { TilingPathInfo::Draw(ref draw_tiling_path_info) => draw_tiling_path_info.paint_id, TilingPathInfo::Clip => PaintId(0), @@ -430,35 +465,35 @@ impl BuiltPath { let tile_bounds = tiles::round_rect_out_to_tile_bounds(tile_map_bounds); let data = match *prepare_mode { - PrepareMode::CPU => { - BuiltPathData::CPU(BuiltPathBinCPUData { - backdrops: vec![0; tile_bounds.width() as usize], - tiles: DenseTileMap::from_builder(|tile_coord| { - TileObjectPrimitive { - tile_x: tile_coord.x() as i16, - tile_y: tile_coord.y() as i16, - alpha_tile_id: AlphaTileId(!0), - path_id, - color: paint_id.0, - backdrop: 0, - ctrl: ctrl_byte, - } - }, tile_bounds), - clip_tiles: match *tiling_path_info { - TilingPathInfo::Draw(_) if clip_path_id.is_some() => { - Some(DenseTileMap::from_builder(|_| { - Clip { - dest_tile_id: AlphaTileId(!0), - dest_backdrop: 0, - src_tile_id: AlphaTileId(!0), - src_backdrop: 0, - } - }, tile_bounds)) - } - _ => None, + PrepareMode::CPU => BuiltPathData::CPU(BuiltPathBinCPUData { + backdrops: vec![0; tile_bounds.width() as usize], + tiles: DenseTileMap::from_builder( + |tile_coord| TileObjectPrimitive { + tile_x: tile_coord.x() as i16, + tile_y: tile_coord.y() as i16, + alpha_tile_id: AlphaTileId(!0), + path_id, + color: paint_id.0, + backdrop: 0, + ctrl: ctrl_byte, }, - }) - } + tile_bounds, + ), + clip_tiles: match *tiling_path_info { + TilingPathInfo::Draw(_) if clip_path_id.is_some() => { + Some(DenseTileMap::from_builder( + |_| Clip { + dest_tile_id: AlphaTileId(!0), + dest_backdrop: 0, + src_tile_id: AlphaTileId(!0), + src_backdrop: 0, + }, + tile_bounds, + )) + } + _ => None, + }, + }), PrepareMode::TransformCPUBinGPU => { BuiltPathData::TransformCPUBinGPU(BuiltPathTransformCPUBinGPUData { outline: Outline::new(), @@ -482,28 +517,37 @@ impl BuiltPath { impl ObjectBuilder { // If `outline` is `None`, then tiling is being done on CPU. Otherwise, it's done on GPU. - pub(crate) fn new(path_id: PathId, - path_bounds: RectF, - view_box_bounds: RectF, - fill_rule: FillRule, - prepare_mode: &PrepareMode, - clip_path_id: Option, - tiling_path_info: &TilingPathInfo) - -> ObjectBuilder { - let built_path = BuiltPath::new(path_id, - path_bounds, - view_box_bounds, - fill_rule, - prepare_mode, - clip_path_id, - tiling_path_info); - ObjectBuilder { built_path, bounds: path_bounds, fills: vec![] } + pub(crate) fn new( + path_id: PathId, + path_bounds: RectF, + view_box_bounds: RectF, + fill_rule: FillRule, + prepare_mode: &PrepareMode, + clip_path_id: Option, + tiling_path_info: &TilingPathInfo, + ) -> ObjectBuilder { + let built_path = BuiltPath::new( + path_id, + path_bounds, + view_box_bounds, + fill_rule, + prepare_mode, + clip_path_id, + tiling_path_info, + ); + ObjectBuilder { + built_path, + bounds: path_bounds, + fills: vec![], + } } - pub(crate) fn add_fill(&mut self, - scene_builder: &SceneBuilder, - segment: LineSegment2F, - tile_coords: Vector2I) { + pub(crate) 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. @@ -519,7 +563,10 @@ impl ObjectBuilder { // Convert to 8.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 (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]); @@ -546,10 +593,11 @@ impl ObjectBuilder { }); } - fn get_or_allocate_alpha_tile_index(&mut self, - scene_builder: &SceneBuilder, - tile_coords: Vector2I) - -> AlphaTileId { + fn get_or_allocate_alpha_tile_index( + &mut self, + scene_builder: &SceneBuilder, + tile_coords: Vector2I, + ) -> AlphaTileId { let local_tile_index = self.tile_coords_to_local_index_unchecked(tile_coords) as usize; let tiles = match self.built_path.data { @@ -595,8 +643,10 @@ impl ObjectBuilder { }; let tile_offset = tile_coords - tiles.rect.origin(); - if tile_offset.x() < 0 || tile_offset.x() >= tiles.rect.width() || - tile_offset.y() >= tiles.rect.height() { + if tile_offset.x() < 0 + || tile_offset.x() >= tiles.rect.width() + || tile_offset.y() >= tiles.rect.height() + { return; } @@ -611,8 +661,11 @@ impl ObjectBuilder { } impl TileBatchDataD3D11 { - fn new(batch_id: TileBatchId, mode: &PrepareMode, path_source: PathSource) - -> TileBatchDataD3D11 { + fn new( + batch_id: TileBatchId, + mode: &PrepareMode, + path_source: PathSource, + ) -> TileBatchDataD3D11 { TileBatchDataD3D11 { batch_id, path_count: 0, @@ -621,53 +674,52 @@ impl TileBatchDataD3D11 { path_source, prepare_info: match *mode { PrepareMode::CPU => unimplemented!(), - PrepareMode::TransformCPUBinGPU => { - PrepareTilesInfoD3D11 { - backdrops: vec![], - propagate_metadata: vec![], - dice_metadata: vec![], - tile_path_info: vec![], - transform: Transform2F::default(), - } - } - PrepareMode::GPU { ref transform } => { - PrepareTilesInfoD3D11 { - backdrops: vec![], - propagate_metadata: vec![], - dice_metadata: vec![], - tile_path_info: vec![], - transform: *transform, - } - } + PrepareMode::TransformCPUBinGPU => PrepareTilesInfoD3D11 { + backdrops: vec![], + propagate_metadata: vec![], + dice_metadata: vec![], + tile_path_info: vec![], + transform: Transform2F::default(), + }, + PrepareMode::GPU { ref transform } => PrepareTilesInfoD3D11 { + backdrops: vec![], + propagate_metadata: vec![], + dice_metadata: vec![], + tile_path_info: vec![], + transform: *transform, + }, }, clipped_path_info: None, } } - fn push(&mut self, - path: &BuiltPath, - global_path_id: PathId, - batch_clip_path_id: Option, - z_write: bool, - sink: &SceneSink) - -> PathBatchIndex { + fn push( + &mut self, + path: &BuiltPath, + global_path_id: PathId, + batch_clip_path_id: Option, + z_write: bool, + sink: &SceneSink, + ) -> PathBatchIndex { let batch_path_index = PathBatchIndex(self.path_count); self.path_count += 1; - self.prepare_info.propagate_metadata.push(PropagateMetadataD3D11 { - tile_rect: path.tile_bounds, - tile_offset: self.tile_count, - path_index: batch_path_index, - z_write: z_write as u32, - clip_path_index: match batch_clip_path_id { - None => PathBatchIndex::none(), - Some(batch_clip_path_id) => batch_clip_path_id.path_index, - }, - backdrop_offset: self.prepare_info.backdrops.len() as u32, - pad0: 0, - pad1: 0, - pad2: 0, - }); + self.prepare_info + .propagate_metadata + .push(PropagateMetadataD3D11 { + tile_rect: path.tile_bounds, + tile_offset: self.tile_count, + path_index: batch_path_index, + z_write: z_write as u32, + clip_path_index: match batch_clip_path_id { + None => PathBatchIndex::none(), + Some(batch_clip_path_id) => batch_clip_path_id.path_index, + }, + backdrop_offset: self.prepare_info.backdrops.len() as u32, + pad0: 0, + pad1: 0, + pad2: 0, + }); match path.data { BuiltPathData::CPU(ref data) => { @@ -681,9 +733,11 @@ impl TileBatchDataD3D11 { } } BuiltPathData::TransformCPUBinGPU(_) | BuiltPathData::GPU => { - init_backdrops(&mut self.prepare_info.backdrops, - batch_path_index, - path.tile_bounds); + init_backdrops( + &mut self.prepare_info.backdrops, + batch_path_index, + path.tile_bounds, + ); } } @@ -695,7 +749,7 @@ impl TileBatchDataD3D11 { }; let segment_range = &segment_ranges[global_path_id.0 as usize]; self.prepare_info.dice_metadata.push(DiceMetadataD3D11 { - first_batch_segment_index: self.segment_count, + first_batch_segment_index: self.segment_count, first_global_segment_index: segment_range.start, global_path_id, pad: 0, @@ -753,11 +807,17 @@ impl TileBatchDataD3D11 { } } -fn init_backdrops(backdrops: &mut Vec, - path_index: PathBatchIndex, - tile_rect: RectI) { +fn init_backdrops( + backdrops: &mut Vec, + path_index: PathBatchIndex, + tile_rect: RectI, +) { for tile_x_offset in 0..tile_rect.width() { - backdrops.push(BackdropInfoD3D11 { initial_backdrop: 0, path_index, tile_x_offset }); + backdrops.push(BackdropInfoD3D11 { + initial_backdrop: 0, + path_index, + tile_x_offset, + }); } } @@ -792,7 +852,10 @@ impl BuiltSegments { impl SegmentsD3D11 { fn new() -> SegmentsD3D11 { - SegmentsD3D11 { points: vec![], indices: vec![] } + SegmentsD3D11 { + points: vec![], + indices: vec![], + } } fn add_path(&mut self, outline: &Outline) -> Range { @@ -802,15 +865,21 @@ impl SegmentsD3D11 { self.points.reserve(point_count as usize); for point_index in 0..point_count { - if !contour.flags_of(point_index).intersects(PointFlags::CONTROL_POINT_0 | - PointFlags::CONTROL_POINT_1) { + if !contour + .flags_of(point_index) + .intersects(PointFlags::CONTROL_POINT_0 | PointFlags::CONTROL_POINT_1) + { let mut flags = 0; - if point_index + 1 < point_count && - contour.flags_of(point_index + 1) - .contains(PointFlags::CONTROL_POINT_0) { - if point_index + 2 < point_count && - contour.flags_of(point_index + 2) - .contains(PointFlags::CONTROL_POINT_1) { + if point_index + 1 < point_count + && contour + .flags_of(point_index + 1) + .contains(PointFlags::CONTROL_POINT_0) + { + if point_index + 2 < point_count + && contour + .flags_of(point_index + 2) + .contains(PointFlags::CONTROL_POINT_1) + { flags = CURVE_IS_CUBIC } else { flags = CURVE_IS_QUADRATIC @@ -854,12 +923,10 @@ impl TileBatchBuilder { draw_commands: vec![], next_batch_id: TileBatchId(MAX_CLIP_BATCHES), clip_batches_d3d11: match built_paths { - None => { - Some(ClipBatchesD3D11 { - prepare_batches: vec![], - clip_id_to_path_batch_index: FxHashMap::default(), - }) - } + None => Some(ClipBatchesD3D11 { + prepare_batches: vec![], + clip_id_to_path_batch_index: FxHashMap::default(), + }), Some(_) => None, }, level: match built_paths { @@ -869,23 +936,27 @@ impl TileBatchBuilder { } } - fn build_tile_batches_for_draw_path_display_item(&mut self, - scene: &Scene, - sink: &SceneSink, - built_options: &PreparedBuildOptions, - draw_path_id_range: Range, - paint_metadata: &[PaintMetadata], - prepare_mode: &PrepareMode) { + fn build_tile_batches_for_draw_path_display_item( + &mut self, + scene: &Scene, + sink: &SceneSink, + built_options: &PreparedBuildOptions, + draw_path_id_range: Range, + paint_metadata: &[PaintMetadata], + prepare_mode: &PrepareMode, + ) { let mut draw_tile_batch = None; for draw_path_id in draw_path_id_range.start.0..draw_path_id_range.end.0 { let draw_path_id = DrawPathId(draw_path_id); let draw_path = match self.level { TileBatchBuilderLevel::D3D11 { .. } => { - match self.prepare_draw_path_for_gpu_binning(scene, - built_options, - draw_path_id, - prepare_mode, - paint_metadata) { + match self.prepare_draw_path_for_gpu_binning( + scene, + built_options, + draw_path_id, + prepare_mode, + paint_metadata, + ) { None => continue, Some(built_draw_path) => Cow::Owned(built_draw_path), } @@ -898,12 +969,16 @@ impl TileBatchBuilder { // Try to reuse the current batch if we can. let flush_needed = match draw_tile_batch { Some(DrawTileBatch::D3D11(ref mut existing_batch)) => { - !fixup_batch_for_new_path_if_possible(&mut existing_batch.color_texture, - &draw_path) + !fixup_batch_for_new_path_if_possible( + &mut existing_batch.color_texture, + &draw_path, + ) } Some(DrawTileBatch::D3D9(ref mut existing_batch)) => { - !fixup_batch_for_new_path_if_possible(&mut existing_batch.color_texture, - &draw_path) + !fixup_batch_for_new_path_if_possible( + &mut existing_batch.color_texture, + &draw_path, + ) } None => false, }; @@ -912,10 +987,12 @@ impl TileBatchBuilder { if flush_needed { match draw_tile_batch.take() { Some(DrawTileBatch::D3D11(batch_to_flush)) => { - self.draw_commands.push(RenderCommand::DrawTilesD3D11(batch_to_flush)); + self.draw_commands + .push(RenderCommand::DrawTilesD3D11(batch_to_flush)); } Some(DrawTileBatch::D3D9(batch_to_flush)) => { - self.draw_commands.push(RenderCommand::DrawTilesD3D9(batch_to_flush)); + self.draw_commands + .push(RenderCommand::DrawTilesD3D9(batch_to_flush)); } _ => {} } @@ -937,9 +1014,11 @@ impl TileBatchBuilder { } TileBatchBuilderLevel::D3D11 { .. } => { Some(DrawTileBatch::D3D11(DrawTileBatchD3D11 { - tile_batch_data: TileBatchDataD3D11::new(self.next_batch_id, - &prepare_mode, - PathSource::Draw), + tile_batch_data: TileBatchDataD3D11::new( + self.next_batch_id, + &prepare_mode, + PathSource::Draw, + ), color_texture: draw_path.color_texture, })) } @@ -950,25 +1029,27 @@ impl TileBatchBuilder { // Add clip path if necessary. let clip_path = match self.clip_batches_d3d11 { None => None, - Some(ref mut clip_batches_d3d11) => { - add_clip_path_to_batch(scene, - sink, - built_options, - draw_path.clip_path_id, - prepare_mode, - 0, - clip_batches_d3d11) - } + Some(ref mut clip_batches_d3d11) => add_clip_path_to_batch( + scene, + sink, + built_options, + draw_path.clip_path_id, + prepare_mode, + 0, + clip_batches_d3d11, + ), }; let draw_tile_batch = draw_tile_batch.as_mut().unwrap(); match *draw_tile_batch { DrawTileBatch::D3D11(ref mut draw_tile_batch) => { - draw_tile_batch.tile_batch_data.push(&draw_path.path, - draw_path_id.to_path_id(), - clip_path, - draw_path.occludes, - sink); + draw_tile_batch.tile_batch_data.push( + &draw_path.path, + draw_path_id.to_path_id(), + clip_path, + draw_path.occludes, + sink, + ); } DrawTileBatch::D3D9(ref mut draw_tile_batch) => { let built_paths = match self.level { @@ -995,9 +1076,10 @@ impl TileBatchBuilder { } let tile_coords = vec2i(tile.tile_x as i32, tile.tile_y as i32); - let z_value = draw_tile_batch.z_buffer_data - .get_mut(tile_coords) - .expect("Z value out of bounds!"); + let z_value = draw_tile_batch + .z_buffer_data + .get_mut(tile_coords) + .expect("Z value out of bounds!"); *z_value = (*z_value).max(draw_path_id.0 as i32); } @@ -1006,8 +1088,9 @@ impl TileBatchBuilder { Some(ref clip_tiles) => clip_tiles, }; for clip_tile in &clip_tiles.data { - if clip_tile.dest_tile_id != AlphaTileId(!0) && - clip_tile.src_tile_id != AlphaTileId(!0) { + if clip_tile.dest_tile_id != AlphaTileId(!0) + && clip_tile.src_tile_id != AlphaTileId(!0) + { draw_tile_batch.clips.push(*clip_tile); } } @@ -1017,22 +1100,25 @@ impl TileBatchBuilder { match draw_tile_batch { Some(DrawTileBatch::D3D11(draw_tile_batch)) => { - self.draw_commands.push(RenderCommand::DrawTilesD3D11(draw_tile_batch)); + self.draw_commands + .push(RenderCommand::DrawTilesD3D11(draw_tile_batch)); } Some(DrawTileBatch::D3D9(draw_tile_batch)) => { - self.draw_commands.push(RenderCommand::DrawTilesD3D9(draw_tile_batch)); + self.draw_commands + .push(RenderCommand::DrawTilesD3D9(draw_tile_batch)); } None => {} } } - fn prepare_draw_path_for_gpu_binning(&self, - scene: &Scene, - built_options: &PreparedBuildOptions, - draw_path_id: DrawPathId, - prepare_mode: &PrepareMode, - paint_metadata: &[PaintMetadata]) - -> Option { + fn prepare_draw_path_for_gpu_binning( + &self, + scene: &Scene, + built_options: &PreparedBuildOptions, + draw_path_id: DrawPathId, + prepare_mode: &PrepareMode, + paint_metadata: &[PaintMetadata], + ) -> Option { let transform = match *prepare_mode { PrepareMode::GPU { transform } => transform, PrepareMode::CPU | PrepareMode::TransformCPUBinGPU => { @@ -1051,17 +1137,19 @@ impl TileBatchBuilder { let paint_id = draw_path.paint(); let paint_metadata = &paint_metadata[paint_id.0 as usize]; - let built_path = BuiltPath::new(draw_path_id.to_path_id(), - path_bounds, - effective_view_box, - draw_path.fill_rule(), - &prepare_mode, - draw_path.clip_path(), - &TilingPathInfo::Draw(DrawTilingPathInfo { - paint_id, - blend_mode: draw_path.blend_mode(), - fill_rule: draw_path.fill_rule(), - })); + let built_path = BuiltPath::new( + draw_path_id.to_path_id(), + path_bounds, + effective_view_box, + draw_path.fill_rule(), + &prepare_mode, + draw_path.clip_path(), + &TilingPathInfo::Draw(DrawTilingPathInfo { + paint_id, + blend_mode: draw_path.blend_mode(), + fill_rule: draw_path.fill_rule(), + }), + ); Some(BuiltDrawPath::new(built_path, draw_path, paint_metadata)) } @@ -1069,7 +1157,8 @@ impl TileBatchBuilder { if let Some(clip_batches_d3d11) = self.clip_batches_d3d11 { for prepare_batch in clip_batches_d3d11.prepare_batches.into_iter().rev() { if prepare_batch.path_count > 0 { - sink.listener.send(RenderCommand::PrepareClipTilesD3D11(prepare_batch)); + sink.listener + .send(RenderCommand::PrepareClipTilesD3D11(prepare_batch)); } } } @@ -1089,52 +1178,61 @@ struct ClipBatchesD3D11 { clip_id_to_path_batch_index: FxHashMap, } -fn add_clip_path_to_batch(scene: &Scene, - sink: &SceneSink, - built_options: &PreparedBuildOptions, - clip_path_id: Option, - prepare_mode: &PrepareMode, - clip_level: usize, - clip_batches_d3d11: &mut ClipBatchesD3D11) - -> Option { +fn add_clip_path_to_batch( + scene: &Scene, + sink: &SceneSink, + built_options: &PreparedBuildOptions, + clip_path_id: Option, + prepare_mode: &PrepareMode, + clip_level: usize, + clip_batches_d3d11: &mut ClipBatchesD3D11, +) -> Option { match clip_path_id { None => None, Some(clip_path_id) => { - match clip_batches_d3d11.clip_id_to_path_batch_index.get(&clip_path_id) { - Some(&clip_path_batch_index) => { - Some(GlobalPathId { - batch_id: TileBatchId(clip_level as u32), - path_index: clip_path_batch_index, - }) - } + match clip_batches_d3d11 + .clip_id_to_path_batch_index + .get(&clip_path_id) + { + Some(&clip_path_batch_index) => Some(GlobalPathId { + batch_id: TileBatchId(clip_level as u32), + path_index: clip_path_batch_index, + }), None => { let PreparedClipPath { built_path: clip_path, - subclip_id - } = prepare_clip_path_for_gpu_binning(scene, - sink, - built_options, - clip_path_id, - prepare_mode, - clip_level, - clip_batches_d3d11); + subclip_id, + } = prepare_clip_path_for_gpu_binning( + scene, + sink, + built_options, + clip_path_id, + prepare_mode, + clip_level, + clip_batches_d3d11, + ); while clip_level >= clip_batches_d3d11.prepare_batches.len() { let clip_tile_batch_id = TileBatchId(clip_batches_d3d11.prepare_batches.len() as u32); - clip_batches_d3d11.prepare_batches - .push(TileBatchDataD3D11::new(clip_tile_batch_id, - &prepare_mode, - PathSource::Clip)); + clip_batches_d3d11 + .prepare_batches + .push(TileBatchDataD3D11::new( + clip_tile_batch_id, + &prepare_mode, + PathSource::Clip, + )); } - let clip_path_batch_index = - clip_batches_d3d11.prepare_batches[clip_level] - .push(&clip_path, - clip_path_id.to_path_id(), - subclip_id, - true, - sink); - clip_batches_d3d11.clip_id_to_path_batch_index.insert(clip_path_id, - clip_path_batch_index); + let clip_path_batch_index = clip_batches_d3d11.prepare_batches[clip_level] + .push( + &clip_path, + clip_path_id.to_path_id(), + subclip_id, + true, + sink, + ); + clip_batches_d3d11 + .clip_id_to_path_batch_index + .insert(clip_path_id, clip_path_batch_index); Some(GlobalPathId { batch_id: TileBatchId(clip_level as u32), path_index: clip_path_batch_index, @@ -1145,14 +1243,15 @@ fn add_clip_path_to_batch(scene: &Scene, } } -fn prepare_clip_path_for_gpu_binning(scene: &Scene, - sink: &SceneSink, - built_options: &PreparedBuildOptions, - clip_path_id: ClipPathId, - prepare_mode: &PrepareMode, - clip_level: usize, - clip_batches_d3d11: &mut ClipBatchesD3D11) - -> PreparedClipPath { +fn prepare_clip_path_for_gpu_binning( + scene: &Scene, + sink: &SceneSink, + built_options: &PreparedBuildOptions, + clip_path_id: ClipPathId, + prepare_mode: &PrepareMode, + clip_level: usize, + clip_batches_d3d11: &mut ClipBatchesD3D11, +) -> PreparedClipPath { let transform = match *prepare_mode { PrepareMode::GPU { transform } => transform, PrepareMode::CPU | PrepareMode::TransformCPUBinGPU => { @@ -1163,27 +1262,34 @@ fn prepare_clip_path_for_gpu_binning(scene: &Scene, let clip_path = scene.get_clip_path(clip_path_id); // Add subclip path if necessary. - let subclip_id = add_clip_path_to_batch(scene, - sink, - built_options, - clip_path.clip_path(), - prepare_mode, - clip_level + 1, - clip_batches_d3d11); + let subclip_id = add_clip_path_to_batch( + scene, + sink, + built_options, + clip_path.clip_path(), + prepare_mode, + clip_level + 1, + clip_batches_d3d11, + ); let path_bounds = transform * clip_path.outline().bounds(); // TODO(pcwalton): Clip to view box! - let built_path = BuiltPath::new(clip_path_id.to_path_id(), - path_bounds, - effective_view_box, - clip_path.fill_rule(), - &prepare_mode, - clip_path.clip_path(), - &TilingPathInfo::Clip); + let built_path = BuiltPath::new( + clip_path_id.to_path_id(), + path_bounds, + effective_view_box, + clip_path.fill_rule(), + &prepare_mode, + clip_path.clip_path(), + &TilingPathInfo::Clip, + ); - PreparedClipPath { built_path, subclip_id } + PreparedClipPath { + built_path, + subclip_id, + } } struct PreparedClipPath { @@ -1191,18 +1297,20 @@ struct PreparedClipPath { subclip_id: Option, } -fn fixup_batch_for_new_path_if_possible(batch_color_texture: &mut Option, - draw_path: &BuiltDrawPath) - -> bool { +fn fixup_batch_for_new_path_if_possible( + batch_color_texture: &mut Option, + draw_path: &BuiltDrawPath, +) -> bool { if draw_path.color_texture.is_some() { if batch_color_texture.is_none() { *batch_color_texture = draw_path.color_texture; return true; } if draw_path.color_texture != *batch_color_texture { - debug!("batch break: path color texture {:?} batch color texture {:?}", - draw_path.color_texture, - batch_color_texture); + debug!( + "batch break: path color texture {:?} batch color texture {:?}", + draw_path.color_texture, batch_color_texture + ); return false; } } diff --git a/renderer/src/concurrent/executor.rs b/renderer/src/concurrent/executor.rs index 3241e725..2e682e44 100644 --- a/renderer/src/concurrent/executor.rs +++ b/renderer/src/concurrent/executor.rs @@ -18,7 +18,9 @@ pub trait Executor { /// (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; + where + T: Send, + F: Fn(usize) -> T + Send + Sync; } /// An executor that simply executes tasks sequentially in the same thread. @@ -26,7 +28,10 @@ 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 { + where + T: Send, + F: Fn(usize) -> T + Send + Sync, + { (0..length).into_iter().map(builder).collect() } } diff --git a/renderer/src/concurrent/rayon.rs b/renderer/src/concurrent/rayon.rs index f61724de..2f4e5f8f 100644 --- a/renderer/src/concurrent/rayon.rs +++ b/renderer/src/concurrent/rayon.rs @@ -18,7 +18,10 @@ 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 { + where + T: Send, + F: Fn(usize) -> T + Send + Sync, + { (0..length).into_par_iter().map(builder).collect() } } diff --git a/renderer/src/concurrent/scene_proxy.rs b/renderer/src/concurrent/scene_proxy.rs index fd59fc5b..ba6d8d34 100644 --- a/renderer/src/concurrent/scene_proxy.rs +++ b/renderer/src/concurrent/scene_proxy.rs @@ -41,24 +41,27 @@ pub struct SceneProxy { impl SceneProxy { /// Creates a new scene proxy using the given renderer GPU API level and executor to execute /// CPU tasks. - /// + /// /// If you want to use multiple threads, you typically pass in a `RayonExecutor` here. If you /// want to use a single thread (perhaps because you're in a WebAssembly environment), pass a /// `SequentialExecutor`. pub fn new(renderer_level: RendererLevel, executor: E) -> SceneProxy - where E: Executor + Send + 'static { + where + E: Executor + Send + 'static, + { SceneProxy::from_scene(Scene::new(), renderer_level, executor) } /// Wraps an existing scene in a scene proxy using the given renderer GPU API level an executor /// to execute CPU tasks. - /// + /// /// If you want to use multiple threads, you typically pass in a `RayonExecutor` here. If you /// want to use a single thread (perhaps because you're in a WebAssembly environment), pass a /// `SequentialExecutor`. - pub fn from_scene(scene: Scene, renderer_level: RendererLevel, executor: E) - -> SceneProxy - where E: Executor + Send + 'static { + pub fn from_scene(scene: Scene, renderer_level: RendererLevel, executor: E) -> SceneProxy + where + E: Executor + Send + 'static, + { let (main_to_worker_sender, main_to_worker_receiver) = flume::bounded(MAX_MESSAGES_IN_FLIGHT); let (worker_to_main_sender, worker_to_main_receiver) = @@ -68,19 +71,26 @@ impl SceneProxy { })); let sink = SceneSink::new(listener, renderer_level); thread::spawn(move || scene_thread(scene, executor, sink, main_to_worker_receiver)); - SceneProxy { sender: main_to_worker_sender, receiver: worker_to_main_receiver } + SceneProxy { + sender: main_to_worker_sender, + receiver: worker_to_main_receiver, + } } /// Replaces the wrapped scene with a new one, discarding the old scene. #[inline] pub fn replace_scene(&self, new_scene: Scene) { - self.sender.send(MainToWorkerMsg::ReplaceScene(new_scene)).unwrap(); + self.sender + .send(MainToWorkerMsg::ReplaceScene(new_scene)) + .unwrap(); } /// Sets the view box of the scene, which defines the visible rectangle. #[inline] pub fn set_view_box(&self, new_view_box: RectF) { - self.sender.send(MainToWorkerMsg::SetViewBox(new_view_box)).unwrap(); + self.sender + .send(MainToWorkerMsg::SetViewBox(new_view_box)) + .unwrap(); } /// Constructs a scene and queues up the commands needed to render it. @@ -91,7 +101,10 @@ impl SceneProxy { /// Sends all queued commands to the given renderer to render the wrapped scene. #[inline] - pub fn render(&mut self, renderer: &mut Renderer) where D: Device { + pub fn render(&mut self, renderer: &mut Renderer) + where + D: Device, + { renderer.begin_scene(); while let Ok(command) = self.receiver.recv() { renderer.render_command(&command); @@ -114,7 +127,9 @@ impl SceneProxy { /// ``` #[inline] pub fn build_and_render(&mut self, renderer: &mut Renderer, build_options: BuildOptions) - where D: Device { + where + D: Device, + { self.build(build_options); self.render(renderer); } @@ -123,16 +138,21 @@ impl SceneProxy { #[inline] pub fn copy_scene(&self) -> Scene { let (sender, receiver) = flume::bounded(MAX_MESSAGES_IN_FLIGHT); - self.sender.send(MainToWorkerMsg::CopyScene(sender)).unwrap(); + self.sender + .send(MainToWorkerMsg::CopyScene(sender)) + .unwrap(); receiver.recv().unwrap() } } -fn scene_thread(mut scene: Scene, - executor: E, - mut sink: SceneSink<'static>, - main_to_worker_receiver: Receiver) - where E: Executor { +fn scene_thread( + mut scene: Scene, + executor: E, + mut sink: SceneSink<'static>, + 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, diff --git a/renderer/src/gpu/blend.rs b/renderer/src/gpu/blend.rs index 02ae3924..66c1c196 100644 --- a/renderer/src/gpu/blend.rs +++ b/renderer/src/gpu/blend.rs @@ -15,25 +15,25 @@ use crate::paint::PaintCompositeOp; use pathfinder_content::effects::BlendMode; use pathfinder_gpu::{BlendFactor, BlendState}; -const COMBINER_CTRL_COLOR_COMBINE_SRC_IN: i32 = 0x1; +const COMBINER_CTRL_COLOR_COMBINE_SRC_IN: i32 = 0x1; const COMBINER_CTRL_COLOR_COMBINE_DEST_IN: i32 = 0x2; -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_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; pub(crate) trait ToBlendState { fn to_blend_state(self) -> Option; @@ -42,121 +42,99 @@ pub(crate) trait ToBlendState { 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 => { + 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 } @@ -171,18 +149,18 @@ pub(crate) trait ToCompositeCtrl { 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::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, @@ -219,33 +197,33 @@ pub trait BlendModeExt { 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, + 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, } } } diff --git a/renderer/src/gpu/d3d11/mod.rs b/renderer/src/gpu/d3d11/mod.rs index b3168830..012e72db 100644 --- a/renderer/src/gpu/d3d11/mod.rs +++ b/renderer/src/gpu/d3d11/mod.rs @@ -9,7 +9,7 @@ // except according to those terms. //! A GPU compute-based renderer that uses functionality available in Direct3D 11. -//! +//! //! This renderer supports OpenGL at least 4.3, OpenGL ES at least 3.1, and Metal of any version. pub mod renderer; diff --git a/renderer/src/gpu/d3d11/renderer.rs b/renderer/src/gpu/d3d11/renderer.rs index 6fdc1c46..606b7f2c 100644 --- a/renderer/src/gpu/d3d11/renderer.rs +++ b/renderer/src/gpu/d3d11/renderer.rs @@ -9,21 +9,21 @@ // except according to those terms. //! A GPU compute-based renderer that uses functionality available in Direct3D 11. -//! +//! //! This renderer supports OpenGL at least 4.3, OpenGL ES at least 3.1, and Metal of any version. -use crate::gpu::d3d11::shaders::{BOUND_WORKGROUP_SIZE, DICE_WORKGROUP_SIZE, BIN_WORKGROUP_SIZE}; -use crate::gpu::d3d11::shaders::{PROPAGATE_WORKGROUP_SIZE, ProgramsD3D11, SORT_WORKGROUP_SIZE}; +use crate::gpu::d3d11::shaders::{ProgramsD3D11, PROPAGATE_WORKGROUP_SIZE, SORT_WORKGROUP_SIZE}; +use crate::gpu::d3d11::shaders::{BIN_WORKGROUP_SIZE, BOUND_WORKGROUP_SIZE, DICE_WORKGROUP_SIZE}; use crate::gpu::perf::TimeCategory; use crate::gpu::renderer::{FramebufferFlags, RendererCore}; use crate::gpu_data::{AlphaTileD3D11, BackdropInfoD3D11, DiceMetadataD3D11, DrawTileBatchD3D11}; use crate::gpu_data::{Fill, FirstTileD3D11, MicrolineD3D11, PathSource, PropagateMetadataD3D11}; -use crate::gpu_data::{SegmentIndicesD3D11, SegmentsD3D11, TileD3D11, TileBatchDataD3D11}; +use crate::gpu_data::{SegmentIndicesD3D11, SegmentsD3D11, TileBatchDataD3D11, TileD3D11}; use crate::gpu_data::{TileBatchTexture, TilePathInfoD3D11}; use byte_slice_cast::AsSliceOf; use pathfinder_geometry::transform2d::Transform2F; use pathfinder_geometry::vector::Vector2F; -use pathfinder_gpu::allocator::{BufferTag, GeneralBufferID, GPUMemoryAllocator}; +use pathfinder_gpu::allocator::{BufferTag, GPUMemoryAllocator, GeneralBufferID}; use pathfinder_gpu::{BufferTarget, ComputeDimensions, ComputeState, Device, ImageAccess}; use pathfinder_gpu::{RenderTarget, UniformData}; use pathfinder_resources::ResourceLoader; @@ -31,19 +31,22 @@ use pathfinder_simd::default::{F32x4, I32x2}; use std::ops::Range; use vec_map::VecMap; -const FILL_INDIRECT_DRAW_PARAMS_INSTANCE_COUNT_INDEX: usize = 1; +const FILL_INDIRECT_DRAW_PARAMS_INSTANCE_COUNT_INDEX: usize = 1; const FILL_INDIRECT_DRAW_PARAMS_ALPHA_TILE_COUNT_INDEX: usize = 4; -const FILL_INDIRECT_DRAW_PARAMS_SIZE: usize = 8; +const FILL_INDIRECT_DRAW_PARAMS_SIZE: usize = 8; -const BIN_INDIRECT_DRAW_PARAMS_MICROLINE_COUNT_INDEX: usize = 3; +const BIN_INDIRECT_DRAW_PARAMS_MICROLINE_COUNT_INDEX: usize = 3; const LOAD_ACTION_CLEAR: i32 = 0; -const LOAD_ACTION_LOAD: i32 = 1; +const LOAD_ACTION_LOAD: i32 = 1; const INITIAL_ALLOCATED_MICROLINE_COUNT: u32 = 1024 * 16; const INITIAL_ALLOCATED_FILL_COUNT: u32 = 1024 * 16; -pub(crate) struct RendererD3D11 where D: Device { +pub(crate) struct RendererD3D11 +where + D: Device, +{ programs: ProgramsD3D11, allocated_microline_count: u32, allocated_fill_count: u32, @@ -51,9 +54,14 @@ pub(crate) struct RendererD3D11 where D: Device { tile_batch_info: VecMap, } -impl RendererD3D11 where D: Device { - pub(crate) fn new(core: &mut RendererCore, resources: &dyn ResourceLoader) - -> RendererD3D11 { +impl RendererD3D11 +where + D: Device, +{ + pub(crate) fn new( + core: &mut RendererCore, + resources: &dyn ResourceLoader, + ) -> RendererD3D11 { let programs = ProgramsD3D11::new(&core.device, resources); RendererD3D11 { programs, @@ -64,112 +72,148 @@ impl RendererD3D11 where D: Device { } } - fn bound(&mut self, - core: &mut RendererCore, - tiles_d3d11_buffer_id: GeneralBufferID, - tile_count: u32, - tile_path_info: &[TilePathInfoD3D11]) { + fn bound( + &mut self, + core: &mut RendererCore, + tiles_d3d11_buffer_id: GeneralBufferID, + tile_count: u32, + tile_path_info: &[TilePathInfoD3D11], + ) { let bound_program = &self.programs.bound_program; - let path_info_buffer_id = - core.allocator - .allocate_general_buffer::(&core.device, - tile_path_info.len() as u64, - BufferTag("TilePathInfoD3D11")); + let path_info_buffer_id = core.allocator.allocate_general_buffer::( + &core.device, + tile_path_info.len() as u64, + BufferTag("TilePathInfoD3D11"), + ); let tile_path_info_buffer = core.allocator.get_general_buffer(path_info_buffer_id); - core.device.upload_to_buffer(tile_path_info_buffer, - 0, - tile_path_info, - BufferTarget::Storage); + core.device.upload_to_buffer( + tile_path_info_buffer, + 0, + tile_path_info, + BufferTarget::Storage, + ); let tiles_buffer = core.allocator.get_general_buffer(tiles_d3d11_buffer_id); - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); let compute_dimensions = ComputeDimensions { x: (tile_count + BOUND_WORKGROUP_SIZE - 1) / BOUND_WORKGROUP_SIZE, y: 1, z: 1, }; - core.device.dispatch_compute(compute_dimensions, &ComputeState { - program: &bound_program.program, - textures: &[], - uniforms: &[ - (&bound_program.path_count_uniform, UniformData::Int(tile_path_info.len() as i32)), - (&bound_program.tile_count_uniform, UniformData::Int(tile_count as i32)), - ], - images: &[], - storage_buffers: &[ - (&bound_program.tile_path_info_storage_buffer, tile_path_info_buffer), - (&bound_program.tiles_storage_buffer, tiles_buffer), - ], - }); + core.device.dispatch_compute( + compute_dimensions, + &ComputeState { + program: &bound_program.program, + textures: &[], + uniforms: &[ + ( + &bound_program.path_count_uniform, + UniformData::Int(tile_path_info.len() as i32), + ), + ( + &bound_program.tile_count_uniform, + UniformData::Int(tile_count as i32), + ), + ], + images: &[], + storage_buffers: &[ + ( + &bound_program.tile_path_info_storage_buffer, + tile_path_info_buffer, + ), + (&bound_program.tiles_storage_buffer, tiles_buffer), + ], + }, + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Other, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Other, timer_query); core.allocator.free_general_buffer(path_info_buffer_id); } - fn upload_propagate_metadata(&mut self, - core: &mut RendererCore, - propagate_metadata: &[PropagateMetadataD3D11], - backdrops: &[BackdropInfoD3D11]) - -> PropagateMetadataBufferIDsD3D11 { - let propagate_metadata_storage_id = - core.allocator.allocate_general_buffer::( + fn upload_propagate_metadata( + &mut self, + core: &mut RendererCore, + propagate_metadata: &[PropagateMetadataD3D11], + backdrops: &[BackdropInfoD3D11], + ) -> PropagateMetadataBufferIDsD3D11 { + let propagate_metadata_storage_id = core + .allocator + .allocate_general_buffer::( &core.device, propagate_metadata.len() as u64, - BufferTag("PropagateMetadataD3D11")); - let propagate_metadata_buffer = - core.allocator.get_general_buffer(propagate_metadata_storage_id); - core.device.upload_to_buffer(propagate_metadata_buffer, - 0, - propagate_metadata, - BufferTarget::Storage); + BufferTag("PropagateMetadataD3D11"), + ); + let propagate_metadata_buffer = core + .allocator + .get_general_buffer(propagate_metadata_storage_id); + core.device.upload_to_buffer( + propagate_metadata_buffer, + 0, + propagate_metadata, + BufferTarget::Storage, + ); let backdrops_storage_id = core.allocator.allocate_general_buffer::( &core.device, backdrops.len() as u64, - BufferTag("BackdropInfoD3D11")); + BufferTag("BackdropInfoD3D11"), + ); PropagateMetadataBufferIDsD3D11 { - propagate_metadata: propagate_metadata_storage_id, - backdrops: backdrops_storage_id, + propagate_metadata: propagate_metadata_storage_id, + backdrops: backdrops_storage_id, } } - fn upload_initial_backdrops(&self, - core: &RendererCore, - backdrops_buffer_id: GeneralBufferID, - backdrops: &[BackdropInfoD3D11]) { + fn upload_initial_backdrops( + &self, + core: &RendererCore, + backdrops_buffer_id: GeneralBufferID, + backdrops: &[BackdropInfoD3D11], + ) { let backdrops_buffer = core.allocator.get_general_buffer(backdrops_buffer_id); - core.device.upload_to_buffer(backdrops_buffer, 0, backdrops, BufferTarget::Storage); + core.device + .upload_to_buffer(backdrops_buffer, 0, backdrops, BufferTarget::Storage); } - fn bin_segments(&mut self, - core: &mut RendererCore, - microlines_storage: &MicrolinesBufferIDsD3D11, - propagate_metadata_buffer_ids: &PropagateMetadataBufferIDsD3D11, - tiles_d3d11_buffer_id: GeneralBufferID, - z_buffer_id: GeneralBufferID) - -> Option { + fn bin_segments( + &mut self, + core: &mut RendererCore, + microlines_storage: &MicrolinesBufferIDsD3D11, + propagate_metadata_buffer_ids: &PropagateMetadataBufferIDsD3D11, + tiles_d3d11_buffer_id: GeneralBufferID, + z_buffer_id: GeneralBufferID, + ) -> Option { let bin_program = &self.programs.bin_program; - let fill_vertex_buffer_id = - core.allocator.allocate_general_buffer::(&core.device, - self.allocated_fill_count as u64, - BufferTag("Fill")); + let fill_vertex_buffer_id = core.allocator.allocate_general_buffer::( + &core.device, + self.allocated_fill_count as u64, + BufferTag("Fill"), + ); let fill_vertex_buffer = core.allocator.get_general_buffer(fill_vertex_buffer_id); - let microlines_buffer = core.allocator.get_general_buffer(microlines_storage.buffer_id); + let microlines_buffer = core + .allocator + .get_general_buffer(microlines_storage.buffer_id); let tiles_buffer = core.allocator.get_general_buffer(tiles_d3d11_buffer_id); - let propagate_metadata_buffer = - core.allocator.get_general_buffer(propagate_metadata_buffer_ids.propagate_metadata); - let backdrops_buffer = - core.allocator.get_general_buffer(propagate_metadata_buffer_ids.backdrops); + let propagate_metadata_buffer = core + .allocator + .get_general_buffer(propagate_metadata_buffer_ids.propagate_metadata); + let backdrops_buffer = core + .allocator + .get_general_buffer(propagate_metadata_buffer_ids.backdrops); // Upload fill indirect draw params to header of the Z-buffer. // @@ -177,13 +221,16 @@ impl RendererD3D11 where D: Device { // some drivers (#373). let z_buffer = core.allocator.get_general_buffer(z_buffer_id); let indirect_draw_params = [6, 0, 0, 0, 0, microlines_storage.count, 0, 0]; - core.device.upload_to_buffer::(&z_buffer, - 0, - &indirect_draw_params, - BufferTarget::Storage); + core.device.upload_to_buffer::( + &z_buffer, + 0, + &indirect_draw_params, + BufferTarget::Storage, + ); - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); let compute_dimensions = ComputeDimensions { x: (microlines_storage.count + BIN_WORKGROUP_SIZE - 1) / BIN_WORKGROUP_SIZE, @@ -191,33 +238,46 @@ impl RendererD3D11 where D: Device { z: 1, }; - core.device.dispatch_compute(compute_dimensions, &ComputeState { - program: &bin_program.program, - textures: &[], - uniforms: &[ - (&bin_program.microline_count_uniform, - UniformData::Int(microlines_storage.count as i32)), - (&bin_program.max_fill_count_uniform, - UniformData::Int(self.allocated_fill_count as i32)), - ], - images: &[], - storage_buffers: &[ - (&bin_program.microlines_storage_buffer, microlines_buffer), - (&bin_program.metadata_storage_buffer, propagate_metadata_buffer), - (&bin_program.indirect_draw_params_storage_buffer, z_buffer), - (&bin_program.fills_storage_buffer, fill_vertex_buffer), - (&bin_program.tiles_storage_buffer, tiles_buffer), - (&bin_program.backdrops_storage_buffer, backdrops_buffer), - ], - }); + core.device.dispatch_compute( + compute_dimensions, + &ComputeState { + program: &bin_program.program, + textures: &[], + uniforms: &[ + ( + &bin_program.microline_count_uniform, + UniformData::Int(microlines_storage.count as i32), + ), + ( + &bin_program.max_fill_count_uniform, + UniformData::Int(self.allocated_fill_count as i32), + ), + ], + images: &[], + storage_buffers: &[ + (&bin_program.microlines_storage_buffer, microlines_buffer), + ( + &bin_program.metadata_storage_buffer, + propagate_metadata_buffer, + ), + (&bin_program.indirect_draw_params_storage_buffer, z_buffer), + (&bin_program.fills_storage_buffer, fill_vertex_buffer), + (&bin_program.tiles_storage_buffer, tiles_buffer), + (&bin_program.backdrops_storage_buffer, backdrops_buffer), + ], + }, + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Bin, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Bin, timer_query); - let indirect_draw_params_receiver = core.device.read_buffer(z_buffer, - BufferTarget::Storage, - 0..32); + let indirect_draw_params_receiver = + core.device + .read_buffer(z_buffer, BufferTarget::Storage, 0..32); let indirect_draw_params = core.device.recv_buffer(&indirect_draw_params_receiver); let indirect_draw_params: &[u32] = indirect_draw_params.as_slice_of().unwrap(); @@ -230,49 +290,65 @@ impl RendererD3D11 where D: Device { core.stats.fill_count += needed_fill_count as usize; - Some(FillBufferInfoD3D11 { fill_vertex_buffer_id }) + Some(FillBufferInfoD3D11 { + fill_vertex_buffer_id, + }) } - pub(crate) fn upload_scene(&mut self, - core: &mut RendererCore, - draw_segments: &SegmentsD3D11, - clip_segments: &SegmentsD3D11) { - self.scene_buffers.upload(&mut core.allocator, &core.device, draw_segments, clip_segments); + pub(crate) fn upload_scene( + &mut self, + core: &mut RendererCore, + draw_segments: &SegmentsD3D11, + clip_segments: &SegmentsD3D11, + ) { + self.scene_buffers.upload( + &mut core.allocator, + &core.device, + draw_segments, + clip_segments, + ); } fn allocate_tiles(&mut self, core: &mut RendererCore, tile_count: u32) -> GeneralBufferID { - core.allocator.allocate_general_buffer::(&core.device, - tile_count as u64, - BufferTag("TileD3D11")) + core.allocator.allocate_general_buffer::( + &core.device, + tile_count as u64, + BufferTag("TileD3D11"), + ) } - fn dice_segments(&mut self, - core: &mut RendererCore, - dice_metadata: &[DiceMetadataD3D11], - batch_segment_count: u32, - path_source: PathSource, - transform: Transform2F) - -> Option { + fn dice_segments( + &mut self, + core: &mut RendererCore, + dice_metadata: &[DiceMetadataD3D11], + batch_segment_count: u32, + path_source: PathSource, + transform: Transform2F, + ) -> Option { let dice_program = &self.programs.dice_program; let microlines_buffer_id = core.allocator.allocate_general_buffer::( &core.device, self.allocated_microline_count as u64, - BufferTag("MicrolineD3D11")); + BufferTag("MicrolineD3D11"), + ); let dice_metadata_buffer_id = core.allocator.allocate_general_buffer::( &core.device, dice_metadata.len() as u64, - BufferTag("DiceMetadataD3D11")); + BufferTag("DiceMetadataD3D11"), + ); let dice_indirect_draw_params_buffer_id = core.allocator.allocate_general_buffer::( &core.device, 8, - BufferTag("DiceIndirectDrawParamsD3D11")); + BufferTag("DiceIndirectDrawParamsD3D11"), + ); let microlines_buffer = core.allocator.get_general_buffer(microlines_buffer_id); let dice_metadata_storage_buffer = core.allocator.get_general_buffer(dice_metadata_buffer_id); - let dice_indirect_draw_params_buffer = - core.allocator.get_general_buffer(dice_indirect_draw_params_buffer_id); + let dice_indirect_draw_params_buffer = core + .allocator + .get_general_buffer(dice_indirect_draw_params_buffer_id); let scene_buffers = &self.scene_buffers; let scene_source_buffers = match path_source { @@ -286,64 +362,102 @@ impl RendererD3D11 where D: Device { .. } = *scene_source_buffers; - let points_buffer = core.allocator.get_general_buffer( - points_buffer_id.expect("Where's the points buffer?")); + let points_buffer = core + .allocator + .get_general_buffer(points_buffer_id.expect("Where's the points buffer?")); let point_indices_buffer = core.allocator.get_general_buffer( - point_indices_buffer_id.expect("Where's the point indices buffer?")); + point_indices_buffer_id.expect("Where's the point indices buffer?"), + ); - core.device.upload_to_buffer(dice_indirect_draw_params_buffer, - 0, - &[0, 0, 0, 0, point_indices_count, 0, 0, 0], - BufferTarget::Storage); - core.device.upload_to_buffer(dice_metadata_storage_buffer, - 0, - dice_metadata, - BufferTarget::Storage); + core.device.upload_to_buffer( + dice_indirect_draw_params_buffer, + 0, + &[0, 0, 0, 0, point_indices_count, 0, 0, 0], + BufferTarget::Storage, + ); + core.device.upload_to_buffer( + dice_metadata_storage_buffer, + 0, + dice_metadata, + BufferTarget::Storage, + ); - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); - let workgroup_count = (batch_segment_count + DICE_WORKGROUP_SIZE - 1) / - DICE_WORKGROUP_SIZE; - let compute_dimensions = ComputeDimensions { x: workgroup_count, y: 1, z: 1 }; + let workgroup_count = (batch_segment_count + DICE_WORKGROUP_SIZE - 1) / DICE_WORKGROUP_SIZE; + let compute_dimensions = ComputeDimensions { + x: workgroup_count, + y: 1, + z: 1, + }; - core.device.dispatch_compute(compute_dimensions, &ComputeState { - program: &dice_program.program, - textures: &[], - uniforms: &[ - (&dice_program.transform_uniform, UniformData::Mat2(transform.matrix.0)), - (&dice_program.translation_uniform, UniformData::Vec2(transform.vector.0)), - (&dice_program.path_count_uniform, - UniformData::Int(dice_metadata.len() as i32)), - (&dice_program.last_batch_segment_index_uniform, - UniformData::Int(batch_segment_count as i32)), - (&dice_program.max_microline_count_uniform, - UniformData::Int(self.allocated_microline_count as i32)), - ], - images: &[], - storage_buffers: &[ - (&dice_program.compute_indirect_params_storage_buffer, - dice_indirect_draw_params_buffer), - (&dice_program.points_storage_buffer, points_buffer), - (&dice_program.input_indices_storage_buffer, point_indices_buffer), - (&dice_program.microlines_storage_buffer, microlines_buffer), - (&dice_program.dice_metadata_storage_buffer, &dice_metadata_storage_buffer), - ], - }); + core.device.dispatch_compute( + compute_dimensions, + &ComputeState { + program: &dice_program.program, + textures: &[], + uniforms: &[ + ( + &dice_program.transform_uniform, + UniformData::Mat2(transform.matrix.0), + ), + ( + &dice_program.translation_uniform, + UniformData::Vec2(transform.vector.0), + ), + ( + &dice_program.path_count_uniform, + UniformData::Int(dice_metadata.len() as i32), + ), + ( + &dice_program.last_batch_segment_index_uniform, + UniformData::Int(batch_segment_count as i32), + ), + ( + &dice_program.max_microline_count_uniform, + UniformData::Int(self.allocated_microline_count as i32), + ), + ], + images: &[], + storage_buffers: &[ + ( + &dice_program.compute_indirect_params_storage_buffer, + dice_indirect_draw_params_buffer, + ), + (&dice_program.points_storage_buffer, points_buffer), + ( + &dice_program.input_indices_storage_buffer, + point_indices_buffer, + ), + (&dice_program.microlines_storage_buffer, microlines_buffer), + ( + &dice_program.dice_metadata_storage_buffer, + &dice_metadata_storage_buffer, + ), + ], + }, + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Dice, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Dice, timer_query); - let indirect_compute_params_receiver = - core.device.read_buffer(&dice_indirect_draw_params_buffer, - BufferTarget::Storage, - 0..32); + let indirect_compute_params_receiver = core.device.read_buffer( + &dice_indirect_draw_params_buffer, + BufferTarget::Storage, + 0..32, + ); let indirect_compute_params = core.device.recv_buffer(&indirect_compute_params_receiver); let indirect_compute_params: &[u32] = indirect_compute_params.as_slice_of().unwrap(); core.allocator.free_general_buffer(dice_metadata_buffer_id); - core.allocator.free_general_buffer(dice_indirect_draw_params_buffer_id); + core.allocator + .free_general_buffer(dice_indirect_draw_params_buffer_id); let microline_count = indirect_compute_params[BIN_INDIRECT_DRAW_PARAMS_MICROLINE_COUNT_INDEX]; @@ -352,22 +466,34 @@ impl RendererD3D11 where D: Device { return None; } - Some(MicrolinesBufferIDsD3D11 { buffer_id: microlines_buffer_id, count: microline_count }) + Some(MicrolinesBufferIDsD3D11 { + buffer_id: microlines_buffer_id, + count: microline_count, + }) } - fn draw_fills(&mut self, - core: &mut RendererCore, - fill_storage_info: &FillBufferInfoD3D11, - tiles_d3d11_buffer_id: GeneralBufferID, - alpha_tiles_buffer_id: GeneralBufferID, - propagate_tiles_info: &PropagateTilesInfoD3D11) { - let &FillBufferInfoD3D11 { fill_vertex_buffer_id } = fill_storage_info; - let &PropagateTilesInfoD3D11 { ref alpha_tile_range } = propagate_tiles_info; + fn draw_fills( + &mut self, + core: &mut RendererCore, + fill_storage_info: &FillBufferInfoD3D11, + tiles_d3d11_buffer_id: GeneralBufferID, + alpha_tiles_buffer_id: GeneralBufferID, + propagate_tiles_info: &PropagateTilesInfoD3D11, + ) { + let &FillBufferInfoD3D11 { + fill_vertex_buffer_id, + } = fill_storage_info; + let &PropagateTilesInfoD3D11 { + ref alpha_tile_range, + } = propagate_tiles_info; let fill_program = &self.programs.fill_program; let fill_vertex_buffer = core.allocator.get_general_buffer(fill_vertex_buffer_id); - let mask_storage = core.mask_storage.as_ref().expect("Where's the mask storage?"); + let mask_storage = core + .mask_storage + .as_ref() + .expect("Where's the mask storage?"); let mask_framebuffer_id = mask_storage.framebuffer_id; let mask_framebuffer = core.allocator.get_framebuffer(mask_framebuffer_id); let image_texture = core.device.framebuffer_texture(mask_framebuffer); @@ -377,8 +503,9 @@ impl RendererD3D11 where D: Device { let area_lut_texture = core.allocator.get_texture(core.area_lut_texture_id); - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); // This setup is an annoying workaround for the 64K limit of compute invocation in OpenGL. let alpha_tile_count = alpha_tile_range.end - alpha_tile_range.start; @@ -388,45 +515,63 @@ impl RendererD3D11 where D: Device { z: 1, }; - core.device.dispatch_compute(dimensions, &ComputeState { - program: &fill_program.program, - textures: &[(&fill_program.area_lut_texture, area_lut_texture)], - images: &[(&fill_program.dest_image, image_texture, ImageAccess::ReadWrite)], - uniforms: &[ - (&fill_program.alpha_tile_range_uniform, - UniformData::IVec2(I32x2::new(alpha_tile_range.start as i32, - alpha_tile_range.end as i32))), - ], - storage_buffers: &[ - (&fill_program.fills_storage_buffer, fill_vertex_buffer), - (&fill_program.tiles_storage_buffer, tiles_d3d11_buffer), - (&fill_program.alpha_tiles_storage_buffer, &alpha_tiles_buffer), - ], - }); + core.device.dispatch_compute( + dimensions, + &ComputeState { + program: &fill_program.program, + textures: &[(&fill_program.area_lut_texture, area_lut_texture)], + images: &[( + &fill_program.dest_image, + image_texture, + ImageAccess::ReadWrite, + )], + uniforms: &[( + &fill_program.alpha_tile_range_uniform, + UniformData::IVec2(I32x2::new( + alpha_tile_range.start as i32, + alpha_tile_range.end as i32, + )), + )], + storage_buffers: &[ + (&fill_program.fills_storage_buffer, fill_vertex_buffer), + (&fill_program.tiles_storage_buffer, tiles_d3d11_buffer), + ( + &fill_program.alpha_tiles_storage_buffer, + &alpha_tiles_buffer, + ), + ], + }, + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Fill, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Fill, timer_query); - core.framebuffer_flags.insert(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY); + core.framebuffer_flags + .insert(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY); } - pub(crate) fn prepare_and_draw_tiles(&mut self, - core: &mut RendererCore, - batch: &DrawTileBatchD3D11) { + pub(crate) fn prepare_and_draw_tiles( + &mut self, + core: &mut RendererCore, + batch: &DrawTileBatchD3D11, + ) { let tile_batch_id = batch.tile_batch_data.batch_id; self.prepare_tiles(core, &batch.tile_batch_data); let batch_info = self.tile_batch_info[tile_batch_id.0 as usize].clone(); - self.draw_tiles(core, - batch_info.tiles_d3d11_buffer_id, - batch_info.first_tile_map_buffer_id, - batch.color_texture); + self.draw_tiles( + core, + batch_info.tiles_d3d11_buffer_id, + batch_info.first_tile_map_buffer_id, + batch.color_texture, + ); } // Computes backdrops, performs clipping, and populates Z buffers on GPU. - pub(crate) fn prepare_tiles(&mut self, - core: &mut RendererCore, - batch: &TileBatchDataD3D11) { + pub(crate) fn prepare_tiles(&mut self, core: &mut RendererCore, batch: &TileBatchDataD3D11) { core.stats.total_tile_count += batch.tile_count as usize; // Upload tiles to GPU or allocate them as appropriate. @@ -439,7 +584,10 @@ impl RendererD3D11 where D: Device { let clip_tile_batch_info = &self.tile_batch_info[clip_batch_id.0 as usize]; let metadata = clip_tile_batch_info.propagate_metadata_buffer_id; let tiles = clip_tile_batch_info.tiles_d3d11_buffer_id; - Some(ClipBufferIDs { metadata: Some(metadata), tiles }) + Some(ClipBufferIDs { + metadata: Some(metadata), + tiles, + }) } None => None, }; @@ -452,20 +600,23 @@ impl RendererD3D11 where D: Device { // Allocate space for tile lists. let first_tile_map_buffer_id = self.allocate_first_tile_map(core); - let propagate_metadata_buffer_ids = - self.upload_propagate_metadata(core, - &batch.prepare_info.propagate_metadata, - &batch.prepare_info.backdrops); + let propagate_metadata_buffer_ids = self.upload_propagate_metadata( + core, + &batch.prepare_info.propagate_metadata, + &batch.prepare_info.backdrops, + ); // Dice (flatten) segments into microlines. We might have to do this twice if our // first attempt runs out of space in the storage buffer. let mut microlines_storage = None; for _ in 0..2 { - microlines_storage = self.dice_segments(core, - &batch.prepare_info.dice_metadata, - batch.segment_count, - batch.path_source, - batch.prepare_info.transform); + microlines_storage = self.dice_segments( + core, + &batch.prepare_info.dice_metadata, + batch.segment_count, + batch.path_source, + batch.prepare_info.transform, + ); if microlines_storage.is_some() { break; } @@ -477,164 +628,228 @@ impl RendererD3D11 where D: Device { // attempt runs out of space in the fill buffer. let mut fill_buffer_info = None; for _ in 0..2 { - self.bound(core, - tiles_d3d11_buffer_id, - batch.tile_count, - &batch.prepare_info.tile_path_info); + self.bound( + core, + tiles_d3d11_buffer_id, + batch.tile_count, + &batch.prepare_info.tile_path_info, + ); - self.upload_initial_backdrops(core, - propagate_metadata_buffer_ids.backdrops, - &batch.prepare_info.backdrops); + self.upload_initial_backdrops( + core, + propagate_metadata_buffer_ids.backdrops, + &batch.prepare_info.backdrops, + ); - fill_buffer_info = self.bin_segments(core, - µlines_storage, - &propagate_metadata_buffer_ids, - tiles_d3d11_buffer_id, - z_buffer_id); + fill_buffer_info = self.bin_segments( + core, + µlines_storage, + &propagate_metadata_buffer_ids, + tiles_d3d11_buffer_id, + z_buffer_id, + ); if fill_buffer_info.is_some() { break; } } - let fill_buffer_info = - fill_buffer_info.expect("Ran out of space for fills when binning!"); + let fill_buffer_info = fill_buffer_info.expect("Ran out of space for fills when binning!"); - core.allocator.free_general_buffer(microlines_storage.buffer_id); + core.allocator + .free_general_buffer(microlines_storage.buffer_id); // TODO(pcwalton): If we run out of space for alpha tile indices, propagate // multiple times. let alpha_tiles_buffer_id = self.allocate_alpha_tile_info(core, batch.tile_count); - let propagate_tiles_info = - self.propagate_tiles(core, - batch.prepare_info.backdrops.len() as u32, - tiles_d3d11_buffer_id, - z_buffer_id, - first_tile_map_buffer_id, - alpha_tiles_buffer_id, - &propagate_metadata_buffer_ids, - clip_buffer_ids.as_ref()); + let propagate_tiles_info = self.propagate_tiles( + core, + batch.prepare_info.backdrops.len() as u32, + tiles_d3d11_buffer_id, + z_buffer_id, + first_tile_map_buffer_id, + alpha_tiles_buffer_id, + &propagate_metadata_buffer_ids, + clip_buffer_ids.as_ref(), + ); - core.allocator.free_general_buffer(propagate_metadata_buffer_ids.backdrops); + core.allocator + .free_general_buffer(propagate_metadata_buffer_ids.backdrops); // FIXME(pcwalton): Don't unconditionally pass true for copying here. core.reallocate_alpha_tile_pages_if_necessary(true); - self.draw_fills(core, - &fill_buffer_info, - tiles_d3d11_buffer_id, - alpha_tiles_buffer_id, - &propagate_tiles_info); + self.draw_fills( + core, + &fill_buffer_info, + tiles_d3d11_buffer_id, + alpha_tiles_buffer_id, + &propagate_tiles_info, + ); - core.allocator.free_general_buffer(fill_buffer_info.fill_vertex_buffer_id); + core.allocator + .free_general_buffer(fill_buffer_info.fill_vertex_buffer_id); core.allocator.free_general_buffer(alpha_tiles_buffer_id); // FIXME(pcwalton): This seems like the wrong place to do this... - self.sort_tiles(core, tiles_d3d11_buffer_id, first_tile_map_buffer_id, z_buffer_id); + self.sort_tiles( + core, + tiles_d3d11_buffer_id, + first_tile_map_buffer_id, + z_buffer_id, + ); // Record tile batch info. - self.tile_batch_info.insert(batch.batch_id.0 as usize, TileBatchInfoD3D11 { - tile_count: batch.tile_count, - z_buffer_id, - tiles_d3d11_buffer_id, - propagate_metadata_buffer_id: propagate_metadata_buffer_ids.propagate_metadata, - first_tile_map_buffer_id, - }); + self.tile_batch_info.insert( + batch.batch_id.0 as usize, + TileBatchInfoD3D11 { + tile_count: batch.tile_count, + z_buffer_id, + tiles_d3d11_buffer_id, + propagate_metadata_buffer_id: propagate_metadata_buffer_ids.propagate_metadata, + first_tile_map_buffer_id, + }, + ); } - fn propagate_tiles(&mut self, - core: &mut RendererCore, - column_count: u32, - tiles_d3d11_buffer_id: GeneralBufferID, - z_buffer_id: GeneralBufferID, - first_tile_map_buffer_id: GeneralBufferID, - alpha_tiles_buffer_id: GeneralBufferID, - propagate_metadata_buffer_ids: &PropagateMetadataBufferIDsD3D11, - clip_buffer_ids: Option<&ClipBufferIDs>) - -> PropagateTilesInfoD3D11 { + fn propagate_tiles( + &mut self, + core: &mut RendererCore, + column_count: u32, + tiles_d3d11_buffer_id: GeneralBufferID, + z_buffer_id: GeneralBufferID, + first_tile_map_buffer_id: GeneralBufferID, + alpha_tiles_buffer_id: GeneralBufferID, + propagate_metadata_buffer_ids: &PropagateMetadataBufferIDsD3D11, + clip_buffer_ids: Option<&ClipBufferIDs>, + ) -> PropagateTilesInfoD3D11 { let propagate_program = &self.programs.propagate_program; let tiles_d3d11_buffer = core.allocator.get_general_buffer(tiles_d3d11_buffer_id); - let propagate_metadata_storage_buffer = - core.allocator.get_general_buffer(propagate_metadata_buffer_ids.propagate_metadata); - let backdrops_storage_buffer = - core.allocator.get_general_buffer(propagate_metadata_buffer_ids.backdrops); + let propagate_metadata_storage_buffer = core + .allocator + .get_general_buffer(propagate_metadata_buffer_ids.propagate_metadata); + let backdrops_storage_buffer = core + .allocator + .get_general_buffer(propagate_metadata_buffer_ids.backdrops); // TODO(pcwalton): Zero out the Z-buffer on GPU? let z_buffer = core.allocator.get_general_buffer(z_buffer_id); let z_buffer_size = core.tile_size(); let tile_area = z_buffer_size.area() as usize; - core.device.upload_to_buffer(z_buffer, 0, &vec![0i32; tile_area], BufferTarget::Storage); + core.device + .upload_to_buffer(z_buffer, 0, &vec![0i32; tile_area], BufferTarget::Storage); // TODO(pcwalton): Initialize the first tiles buffer on GPU? - let first_tile_map_storage_buffer = core.allocator - .get_general_buffer(first_tile_map_buffer_id); - core.device.upload_to_buffer::(&first_tile_map_storage_buffer, - 0, - &vec![FirstTileD3D11::default(); tile_area], - BufferTarget::Storage); + let first_tile_map_storage_buffer = + core.allocator.get_general_buffer(first_tile_map_buffer_id); + core.device.upload_to_buffer::( + &first_tile_map_storage_buffer, + 0, + &vec![FirstTileD3D11::default(); tile_area], + BufferTarget::Storage, + ); let alpha_tiles_storage_buffer = core.allocator.get_general_buffer(alpha_tiles_buffer_id); let mut storage_buffers = vec![ - (&propagate_program.draw_metadata_storage_buffer, propagate_metadata_storage_buffer), - (&propagate_program.backdrops_storage_buffer, &backdrops_storage_buffer), - (&propagate_program.draw_tiles_storage_buffer, tiles_d3d11_buffer), + ( + &propagate_program.draw_metadata_storage_buffer, + propagate_metadata_storage_buffer, + ), + ( + &propagate_program.backdrops_storage_buffer, + &backdrops_storage_buffer, + ), + ( + &propagate_program.draw_tiles_storage_buffer, + tiles_d3d11_buffer, + ), (&propagate_program.z_buffer_storage_buffer, z_buffer), - (&propagate_program.first_tile_map_storage_buffer, first_tile_map_storage_buffer), - (&propagate_program.alpha_tiles_storage_buffer, alpha_tiles_storage_buffer), + ( + &propagate_program.first_tile_map_storage_buffer, + first_tile_map_storage_buffer, + ), + ( + &propagate_program.alpha_tiles_storage_buffer, + alpha_tiles_storage_buffer, + ), ]; match clip_buffer_ids { Some(clip_buffer_ids) => { - let clip_metadata_buffer_id = - clip_buffer_ids.metadata.expect("Where's the clip metadata storage?"); - let clip_metadata_buffer = core.allocator - .get_general_buffer(clip_metadata_buffer_id); + let clip_metadata_buffer_id = clip_buffer_ids + .metadata + .expect("Where's the clip metadata storage?"); + let clip_metadata_buffer = + core.allocator.get_general_buffer(clip_metadata_buffer_id); let clip_tile_buffer = core.allocator.get_general_buffer(clip_buffer_ids.tiles); - storage_buffers.push((&propagate_program.clip_metadata_storage_buffer, - clip_metadata_buffer)); - storage_buffers.push((&propagate_program.clip_tiles_storage_buffer, - clip_tile_buffer)); + storage_buffers.push(( + &propagate_program.clip_metadata_storage_buffer, + clip_metadata_buffer, + )); + storage_buffers.push(( + &propagate_program.clip_tiles_storage_buffer, + clip_tile_buffer, + )); } None => { // Just attach any old buffers to these, to satisfy Metal. - storage_buffers.push((&propagate_program.clip_metadata_storage_buffer, - propagate_metadata_storage_buffer)); - storage_buffers.push((&propagate_program.clip_tiles_storage_buffer, - tiles_d3d11_buffer)); + storage_buffers.push(( + &propagate_program.clip_metadata_storage_buffer, + propagate_metadata_storage_buffer, + )); + storage_buffers.push(( + &propagate_program.clip_tiles_storage_buffer, + tiles_d3d11_buffer, + )); } } - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); let dimensions = ComputeDimensions { x: (column_count + PROPAGATE_WORKGROUP_SIZE - 1) / PROPAGATE_WORKGROUP_SIZE, y: 1, z: 1, }; - core.device.dispatch_compute(dimensions, &ComputeState { - program: &propagate_program.program, - textures: &[], - images: &[], - uniforms: &[ - (&propagate_program.framebuffer_tile_size_uniform, - UniformData::IVec2(core.framebuffer_tile_size().0)), - (&propagate_program.column_count_uniform, UniformData::Int(column_count as i32)), - (&propagate_program.first_alpha_tile_index_uniform, - UniformData::Int(core.alpha_tile_count as i32)), - ], - storage_buffers: &storage_buffers, - }); + core.device.dispatch_compute( + dimensions, + &ComputeState { + program: &propagate_program.program, + textures: &[], + images: &[], + uniforms: &[ + ( + &propagate_program.framebuffer_tile_size_uniform, + UniformData::IVec2(core.framebuffer_tile_size().0), + ), + ( + &propagate_program.column_count_uniform, + UniformData::Int(column_count as i32), + ), + ( + &propagate_program.first_alpha_tile_index_uniform, + UniformData::Int(core.alpha_tile_count as i32), + ), + ], + storage_buffers: &storage_buffers, + }, + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Other, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Other, timer_query); let fill_indirect_draw_params_receiver = - core.device.read_buffer(&z_buffer, BufferTarget::Storage, 0..32); - let fill_indirect_draw_params = core.device - .recv_buffer(&fill_indirect_draw_params_receiver); + core.device + .read_buffer(&z_buffer, BufferTarget::Storage, 0..32); + let fill_indirect_draw_params = + core.device.recv_buffer(&fill_indirect_draw_params_receiver); let fill_indirect_draw_params: &[u32] = fill_indirect_draw_params.as_slice_of().unwrap(); let batch_alpha_tile_count = @@ -645,14 +860,18 @@ impl RendererD3D11 where D: Device { core.stats.alpha_tile_count += batch_alpha_tile_count as usize; let alpha_tile_end = core.alpha_tile_count; - PropagateTilesInfoD3D11 { alpha_tile_range: alpha_tile_start..alpha_tile_end } + PropagateTilesInfoD3D11 { + alpha_tile_range: alpha_tile_start..alpha_tile_end, + } } - fn sort_tiles(&mut self, - core: &mut RendererCore, - tiles_d3d11_buffer_id: GeneralBufferID, - first_tile_map_buffer_id: GeneralBufferID, - z_buffer_id: GeneralBufferID) { + fn sort_tiles( + &mut self, + core: &mut RendererCore, + tiles_d3d11_buffer_id: GeneralBufferID, + first_tile_map_buffer_id: GeneralBufferID, + z_buffer_id: GeneralBufferID, + ) { let sort_program = &self.programs.sort_program; let tiles_d3d11_buffer = core.allocator.get_general_buffer(tiles_d3d11_buffer_id); @@ -661,100 +880,138 @@ impl RendererD3D11 where D: Device { let tile_count = core.framebuffer_tile_size().area(); - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); let dimensions = ComputeDimensions { x: (tile_count as u32 + SORT_WORKGROUP_SIZE - 1) / SORT_WORKGROUP_SIZE, y: 1, z: 1, }; - core.device.dispatch_compute(dimensions, &ComputeState { - program: &sort_program.program, - textures: &[], - images: &[], - uniforms: &[(&sort_program.tile_count_uniform, UniformData::Int(tile_count))], - storage_buffers: &[ - (&sort_program.tiles_storage_buffer, tiles_d3d11_buffer), - (&sort_program.first_tile_map_storage_buffer, first_tile_map_buffer), - (&sort_program.z_buffer_storage_buffer, z_buffer), - ], - }); + core.device.dispatch_compute( + dimensions, + &ComputeState { + program: &sort_program.program, + textures: &[], + images: &[], + uniforms: &[( + &sort_program.tile_count_uniform, + UniformData::Int(tile_count), + )], + storage_buffers: &[ + (&sort_program.tiles_storage_buffer, tiles_d3d11_buffer), + ( + &sort_program.first_tile_map_storage_buffer, + first_tile_map_buffer, + ), + (&sort_program.z_buffer_storage_buffer, z_buffer), + ], + }, + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Other, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Other, timer_query); } fn allocate_first_tile_map(&mut self, core: &mut RendererCore) -> GeneralBufferID { - core.allocator.allocate_general_buffer::(&core.device, - core.tile_size().area() as u64, - BufferTag("FirstTileD3D11")) + core.allocator.allocate_general_buffer::( + &core.device, + core.tile_size().area() as u64, + BufferTag("FirstTileD3D11"), + ) } - fn allocate_alpha_tile_info(&mut self, core: &mut RendererCore, index_count: u32) - -> GeneralBufferID { - core.allocator.allocate_general_buffer::(&core.device, - index_count as u64, - BufferTag("AlphaTileD3D11")) + fn allocate_alpha_tile_info( + &mut self, + core: &mut RendererCore, + index_count: u32, + ) -> GeneralBufferID { + core.allocator.allocate_general_buffer::( + &core.device, + index_count as u64, + BufferTag("AlphaTileD3D11"), + ) } fn allocate_z_buffer(&mut self, core: &mut RendererCore) -> GeneralBufferID { // This includes the fill indirect draw params because some drivers limit the number of // SSBOs to 8 (#373). let size = core.tile_size().area() as u64 + FILL_INDIRECT_DRAW_PARAMS_SIZE as u64; - core.allocator.allocate_general_buffer::(&core.device, - size, - BufferTag("ZBufferD3D11")) + core.allocator + .allocate_general_buffer::(&core.device, size, BufferTag("ZBufferD3D11")) } - pub(crate) fn draw_tiles(&mut self, - core: &mut RendererCore, - tiles_d3d11_buffer_id: GeneralBufferID, - first_tile_map_buffer_id: GeneralBufferID, - color_texture_0: Option) { - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + pub(crate) fn draw_tiles( + &mut self, + core: &mut RendererCore, + tiles_d3d11_buffer_id: GeneralBufferID, + first_tile_map_buffer_id: GeneralBufferID, + color_texture_0: Option, + ) { + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); let tile_program = &self.programs.tile_program; let (mut textures, mut uniforms, mut images) = (vec![], vec![], vec![]); - core.set_uniforms_for_drawing_tiles(&tile_program.common, - &mut textures, - &mut uniforms, - color_texture_0); + core.set_uniforms_for_drawing_tiles( + &tile_program.common, + &mut textures, + &mut uniforms, + color_texture_0, + ); - uniforms.push((&tile_program.framebuffer_tile_size_uniform, - UniformData::IVec2(core.framebuffer_tile_size().0))); + uniforms.push(( + &tile_program.framebuffer_tile_size_uniform, + UniformData::IVec2(core.framebuffer_tile_size().0), + )); match core.draw_render_target() { RenderTarget::Default => panic!("Can't draw to the default framebuffer with compute!"), RenderTarget::Framebuffer(ref framebuffer) => { let dest_texture = core.device.framebuffer_texture(framebuffer); - images.push((&tile_program.dest_image, dest_texture, ImageAccess::ReadWrite)); + images.push(( + &tile_program.dest_image, + dest_texture, + ImageAccess::ReadWrite, + )); } } let clear_color = core.clear_color_for_draw_operation(); match clear_color { None => { - uniforms.push((&tile_program.load_action_uniform, - UniformData::Int(LOAD_ACTION_LOAD))); - uniforms.push((&tile_program.clear_color_uniform, - UniformData::Vec4(F32x4::default()))); + uniforms.push(( + &tile_program.load_action_uniform, + UniformData::Int(LOAD_ACTION_LOAD), + )); + uniforms.push(( + &tile_program.clear_color_uniform, + UniformData::Vec4(F32x4::default()), + )); } Some(clear_color) => { - uniforms.push((&tile_program.load_action_uniform, - UniformData::Int(LOAD_ACTION_CLEAR))); - uniforms.push((&tile_program.clear_color_uniform, - UniformData::Vec4(clear_color.0))); + uniforms.push(( + &tile_program.load_action_uniform, + UniformData::Int(LOAD_ACTION_CLEAR), + )); + uniforms.push(( + &tile_program.clear_color_uniform, + UniformData::Vec4(clear_color.0), + )); } } let tiles_d3d11_buffer = core.allocator.get_general_buffer(tiles_d3d11_buffer_id); - let first_tile_map_storage_buffer = core.allocator - .get_general_buffer(first_tile_map_buffer_id); + let first_tile_map_storage_buffer = + core.allocator.get_general_buffer(first_tile_map_buffer_id); let framebuffer_tile_size = core.framebuffer_tile_size().0; let compute_dimensions = ComputeDimensions { @@ -763,20 +1020,29 @@ impl RendererD3D11 where D: Device { z: 1, }; - core.device.dispatch_compute(compute_dimensions, &ComputeState { - program: &tile_program.common.program, - textures: &textures, - images: &images, - storage_buffers: &[ - (&tile_program.tiles_storage_buffer, tiles_d3d11_buffer), - (&tile_program.first_tile_map_storage_buffer, first_tile_map_storage_buffer), - ], - uniforms: &uniforms, - }); + core.device.dispatch_compute( + compute_dimensions, + &ComputeState { + program: &tile_program.common.program, + textures: &textures, + images: &images, + storage_buffers: &[ + (&tile_program.tiles_storage_buffer, tiles_d3d11_buffer), + ( + &tile_program.first_tile_map_storage_buffer, + first_tile_map_storage_buffer, + ), + ], + uniforms: &uniforms, + }, + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Composite, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Composite, timer_query); core.preserve_draw_framebuffer(); } @@ -787,10 +1053,14 @@ impl RendererD3D11 where D: Device { fn free_tile_batch_buffers(&mut self, core: &mut RendererCore) { for (_, tile_batch_info) in self.tile_batch_info.drain() { - core.allocator.free_general_buffer(tile_batch_info.z_buffer_id); - core.allocator.free_general_buffer(tile_batch_info.tiles_d3d11_buffer_id); - core.allocator.free_general_buffer(tile_batch_info.propagate_metadata_buffer_id); - core.allocator.free_general_buffer(tile_batch_info.first_tile_map_buffer_id); + core.allocator + .free_general_buffer(tile_batch_info.z_buffer_id); + core.allocator + .free_general_buffer(tile_batch_info.tiles_d3d11_buffer_id); + core.allocator + .free_general_buffer(tile_batch_info.propagate_metadata_buffer_id); + core.allocator + .free_general_buffer(tile_batch_info.first_tile_map_buffer_id); } } } @@ -848,15 +1118,21 @@ struct PropagateTilesInfoD3D11 { impl SceneBuffers { fn new() -> SceneBuffers { - SceneBuffers { draw: SceneSourceBuffers::new(), clip: SceneSourceBuffers::new() } + SceneBuffers { + draw: SceneSourceBuffers::new(), + clip: SceneSourceBuffers::new(), + } } - fn upload(&mut self, - allocator: &mut GPUMemoryAllocator, - device: &D, - draw_segments: &SegmentsD3D11, - clip_segments: &SegmentsD3D11) - where D: Device { + fn upload( + &mut self, + allocator: &mut GPUMemoryAllocator, + device: &D, + draw_segments: &SegmentsD3D11, + clip_segments: &SegmentsD3D11, + ) where + D: Device, + { self.draw.upload(allocator, device, draw_segments); self.clip.upload(allocator, device, clip_segments); } @@ -873,18 +1149,22 @@ impl SceneSourceBuffers { } } - fn upload(&mut self, - allocator: &mut GPUMemoryAllocator, - device: &D, - segments: &SegmentsD3D11) - where D: Device { + fn upload( + &mut self, + allocator: &mut GPUMemoryAllocator, + device: &D, + segments: &SegmentsD3D11, + ) where + D: Device, + { let needed_points_capacity = (segments.points.len() as u32).next_power_of_two(); let needed_point_indices_capacity = (segments.indices.len() as u32).next_power_of_two(); if self.points_capacity < needed_points_capacity { - self.points_buffer = - Some(allocator.allocate_general_buffer::(device, - needed_points_capacity as u64, - BufferTag("PointsD3D11"))); + self.points_buffer = Some(allocator.allocate_general_buffer::( + device, + needed_points_capacity as u64, + BufferTag("PointsD3D11"), + )); self.points_capacity = needed_points_capacity; } if self.point_indices_capacity < needed_point_indices_capacity { @@ -892,17 +1172,22 @@ impl SceneSourceBuffers { Some(allocator.allocate_general_buffer::( device, needed_point_indices_capacity as u64, - BufferTag("PointIndicesD3D11"))); + BufferTag("PointIndicesD3D11"), + )); self.point_indices_capacity = needed_point_indices_capacity; } - device.upload_to_buffer(allocator.get_general_buffer(self.points_buffer.unwrap()), - 0, - &segments.points, - BufferTarget::Storage); - device.upload_to_buffer(allocator.get_general_buffer(self.point_indices_buffer.unwrap()), - 0, - &segments.indices, - BufferTarget::Storage); + device.upload_to_buffer( + allocator.get_general_buffer(self.points_buffer.unwrap()), + 0, + &segments.points, + BufferTarget::Storage, + ); + device.upload_to_buffer( + allocator.get_general_buffer(self.point_indices_buffer.unwrap()), + 0, + &segments.indices, + BufferTarget::Storage, + ); self.point_indices_count = segments.indices.len() as u32; } } diff --git a/renderer/src/gpu/d3d11/shaders.rs b/renderer/src/gpu/d3d11/shaders.rs index d5efdf5e..5e48ac8e 100644 --- a/renderer/src/gpu/d3d11/shaders.rs +++ b/renderer/src/gpu/d3d11/shaders.rs @@ -21,7 +21,10 @@ pub(crate) const BIN_WORKGROUP_SIZE: u32 = 64; pub(crate) const PROPAGATE_WORKGROUP_SIZE: u32 = 64; pub(crate) const SORT_WORKGROUP_SIZE: u32 = 64; -pub(crate) struct ProgramsD3D11 where D: Device { +pub(crate) struct ProgramsD3D11 +where + D: Device, +{ pub(crate) bound_program: BoundProgramD3D11, pub(crate) dice_program: DiceProgramD3D11, pub(crate) bin_program: BinProgramD3D11, @@ -31,7 +34,10 @@ pub(crate) struct ProgramsD3D11 where D: Device { pub(crate) tile_program: TileProgramD3D11, } -impl ProgramsD3D11 where D: Device { +impl ProgramsD3D11 +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> ProgramsD3D11 { ProgramsD3D11 { bound_program: BoundProgramD3D11::new(device, resources), @@ -45,7 +51,10 @@ impl ProgramsD3D11 where D: Device { } } -pub(crate) struct PropagateProgramD3D11 where D: Device { +pub(crate) struct PropagateProgramD3D11 +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) framebuffer_tile_size_uniform: D::Uniform, pub(crate) column_count_uniform: D::Uniform, @@ -60,10 +69,17 @@ pub(crate) struct PropagateProgramD3D11 where D: Device { pub(crate) alpha_tiles_storage_buffer: D::StorageBuffer, } -impl PropagateProgramD3D11 where D: Device { +impl PropagateProgramD3D11 +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> PropagateProgramD3D11 { let mut program = device.create_compute_program(resources, "d3d11/propagate"); - let local_size = ComputeDimensions { x: PROPAGATE_WORKGROUP_SIZE, y: 1, z: 1 }; + let local_size = ComputeDimensions { + x: PROPAGATE_WORKGROUP_SIZE, + y: 1, + z: 1, + }; device.set_compute_program_local_size(&mut program, local_size); let framebuffer_tile_size_uniform = device.get_uniform(&program, "FramebufferTileSize"); @@ -95,7 +111,10 @@ impl PropagateProgramD3D11 where D: Device { } } -pub(crate) struct FillProgramD3D11 where D: Device { +pub(crate) struct FillProgramD3D11 +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) dest_image: D::ImageParameter, pub(crate) area_lut_texture: D::TextureParameter, @@ -105,10 +124,17 @@ pub(crate) struct FillProgramD3D11 where D: Device { pub(crate) alpha_tiles_storage_buffer: D::StorageBuffer, } -impl FillProgramD3D11 where D: Device { +impl FillProgramD3D11 +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> FillProgramD3D11 { let mut program = device.create_compute_program(resources, "d3d11/fill"); - let local_size = ComputeDimensions { x: TILE_WIDTH, y: TILE_HEIGHT / 4, z: 1 }; + 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_image = device.get_image_parameter(&program, "Dest"); @@ -130,7 +156,10 @@ impl FillProgramD3D11 where D: Device { } } -pub(crate) struct TileProgramD3D11 where D: Device { +pub(crate) struct TileProgramD3D11 +where + D: Device, +{ pub(crate) common: TileProgramCommon, pub(crate) load_action_uniform: D::Uniform, pub(crate) clear_color_uniform: D::Uniform, @@ -140,11 +169,14 @@ pub(crate) struct TileProgramD3D11 where D: Device { pub(crate) first_tile_map_storage_buffer: D::StorageBuffer, } -impl TileProgramD3D11 where D: Device { +impl TileProgramD3D11 +where + D: Device, +{ fn new(device: &D, resources: &dyn ResourceLoader) -> TileProgramD3D11 { let mut program = device.create_compute_program(resources, "d3d11/tile"); - device.set_compute_program_local_size(&mut program, - ComputeDimensions { x: 16, y: 4, z: 1 }); + device + .set_compute_program_local_size(&mut program, ComputeDimensions { x: 16, y: 4, z: 1 }); let load_action_uniform = device.get_uniform(&program, "LoadAction"); let clear_color_uniform = device.get_uniform(&program, "ClearColor"); @@ -166,7 +198,10 @@ impl TileProgramD3D11 where D: Device { } } -pub(crate) struct BinProgramD3D11 where D: Device { +pub(crate) struct BinProgramD3D11 +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) microline_count_uniform: D::Uniform, pub(crate) max_fill_count_uniform: D::Uniform, @@ -178,10 +213,17 @@ pub(crate) struct BinProgramD3D11 where D: Device { pub(crate) backdrops_storage_buffer: D::StorageBuffer, } -impl BinProgramD3D11 where D: Device { +impl BinProgramD3D11 +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> BinProgramD3D11 { let mut program = device.create_compute_program(resources, "d3d11/bin"); - let dimensions = ComputeDimensions { x: BIN_WORKGROUP_SIZE, y: 1, z: 1 }; + let dimensions = ComputeDimensions { + x: BIN_WORKGROUP_SIZE, + y: 1, + z: 1, + }; device.set_compute_program_local_size(&mut program, dimensions); let microline_count_uniform = device.get_uniform(&program, "MicrolineCount"); @@ -209,7 +251,10 @@ impl BinProgramD3D11 where D: Device { } } -pub(crate) struct DiceProgramD3D11 where D: Device { +pub(crate) struct DiceProgramD3D11 +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) transform_uniform: D::Uniform, pub(crate) translation_uniform: D::Uniform, @@ -223,17 +268,24 @@ pub(crate) struct DiceProgramD3D11 where D: Device { pub(crate) microlines_storage_buffer: D::StorageBuffer, } -impl DiceProgramD3D11 where D: Device { +impl DiceProgramD3D11 +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> DiceProgramD3D11 { let mut program = device.create_compute_program(resources, "d3d11/dice"); - let dimensions = ComputeDimensions { x: DICE_WORKGROUP_SIZE, y: 1, z: 1 }; + let dimensions = ComputeDimensions { + x: DICE_WORKGROUP_SIZE, + y: 1, + z: 1, + }; device.set_compute_program_local_size(&mut program, dimensions); let transform_uniform = device.get_uniform(&program, "Transform"); let translation_uniform = device.get_uniform(&program, "Translation"); let path_count_uniform = device.get_uniform(&program, "PathCount"); - let last_batch_segment_index_uniform = device.get_uniform(&program, - "LastBatchSegmentIndex"); + let last_batch_segment_index_uniform = + device.get_uniform(&program, "LastBatchSegmentIndex"); let max_microline_count_uniform = device.get_uniform(&program, "MaxMicrolineCount"); let compute_indirect_params_storage_buffer = @@ -259,7 +311,10 @@ impl DiceProgramD3D11 where D: Device { } } -pub(crate) struct BoundProgramD3D11 where D: Device { +pub(crate) struct BoundProgramD3D11 +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) path_count_uniform: D::Uniform, pub(crate) tile_count_uniform: D::Uniform, @@ -267,10 +322,17 @@ pub(crate) struct BoundProgramD3D11 where D: Device { pub(crate) tiles_storage_buffer: D::StorageBuffer, } -impl BoundProgramD3D11 where D: Device { +impl BoundProgramD3D11 +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> BoundProgramD3D11 { let mut program = device.create_compute_program(resources, "d3d11/bound"); - let dimensions = ComputeDimensions { x: BOUND_WORKGROUP_SIZE, y: 1, z: 1 }; + let dimensions = ComputeDimensions { + x: BOUND_WORKGROUP_SIZE, + y: 1, + z: 1, + }; device.set_compute_program_local_size(&mut program, dimensions); let path_count_uniform = device.get_uniform(&program, "PathCount"); @@ -289,7 +351,10 @@ impl BoundProgramD3D11 where D: Device { } } -pub(crate) struct SortProgramD3D11 where D: Device { +pub(crate) struct SortProgramD3D11 +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) tile_count_uniform: D::Uniform, pub(crate) tiles_storage_buffer: D::StorageBuffer, @@ -297,10 +362,17 @@ pub(crate) struct SortProgramD3D11 where D: Device { pub(crate) z_buffer_storage_buffer: D::StorageBuffer, } -impl SortProgramD3D11 where D: Device { +impl SortProgramD3D11 +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> SortProgramD3D11 { let mut program = device.create_compute_program(resources, "d3d11/sort"); - let dimensions = ComputeDimensions { x: SORT_WORKGROUP_SIZE, y: 1, z: 1 }; + let dimensions = ComputeDimensions { + x: SORT_WORKGROUP_SIZE, + y: 1, + z: 1, + }; device.set_compute_program_local_size(&mut program, dimensions); let tile_count_uniform = device.get_uniform(&program, "TileCount"); @@ -316,4 +388,4 @@ impl SortProgramD3D11 where D: Device { z_buffer_storage_buffer, } } -} \ No newline at end of file +} diff --git a/renderer/src/gpu/d3d9/mod.rs b/renderer/src/gpu/d3d9/mod.rs index 0383770c..3a530080 100644 --- a/renderer/src/gpu/d3d9/mod.rs +++ b/renderer/src/gpu/d3d9/mod.rs @@ -9,7 +9,7 @@ // except according to those terms. //! A hybrid CPU-GPU renderer that only relies on functionality available in Direct3D 9. -//! +//! //! This renderer supports OpenGL at least 3.0, OpenGL ES at least 3.0, Metal of any version, and //! WebGL at least 2.0. diff --git a/renderer/src/gpu/d3d9/renderer.rs b/renderer/src/gpu/d3d9/renderer.rs index d3295e78..87a6d8aa 100644 --- a/renderer/src/gpu/d3d9/renderer.rs +++ b/renderer/src/gpu/d3d9/renderer.rs @@ -9,17 +9,17 @@ // except according to those terms. //! A hybrid CPU-GPU renderer that only relies on functionality available in Direct3D 9. -//! +//! //! This renderer supports OpenGL at least 3.0, OpenGL ES at least 3.0, Metal of any version, and //! WebGL at least 2.0. use crate::gpu::blend::{BlendModeExt, ToBlendState}; -use crate::gpu::perf::TimeCategory; -use crate::gpu::renderer::{FramebufferFlags, MASK_FRAMEBUFFER_HEIGHT, MASK_FRAMEBUFFER_WIDTH}; -use crate::gpu::renderer::{RendererCore, RendererFlags}; use crate::gpu::d3d9::shaders::{ClipTileCombineVertexArrayD3D9, ClipTileCopyVertexArrayD3D9}; use crate::gpu::d3d9::shaders::{CopyTileVertexArray, FillVertexArrayD3D9}; use crate::gpu::d3d9::shaders::{ProgramsD3D9, TileVertexArrayD3D9}; +use crate::gpu::perf::TimeCategory; +use crate::gpu::renderer::{FramebufferFlags, MASK_FRAMEBUFFER_HEIGHT, MASK_FRAMEBUFFER_WIDTH}; +use crate::gpu::renderer::{RendererCore, RendererFlags}; use crate::gpu_data::{Clip, DrawTileBatchD3D9, Fill, TileBatchTexture, TileObjectPrimitive}; use crate::tile_map::DenseTileMap; use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; @@ -28,7 +28,7 @@ use pathfinder_color::ColorF; use pathfinder_content::effects::BlendMode; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::transform3d::Transform4F; -use pathfinder_geometry::vector::{Vector2I, Vector4F, vec2i}; +use pathfinder_geometry::vector::{vec2i, Vector2I, Vector4F}; use pathfinder_gpu::allocator::{BufferTag, FramebufferID, FramebufferTag, GeneralBufferID}; use pathfinder_gpu::allocator::{IndexBufferID, TextureID, TextureTag}; use pathfinder_gpu::{BlendFactor, BlendState, BufferTarget, ClearOps, Device, Primitive}; @@ -40,7 +40,10 @@ use std::u32; const MAX_FILLS_PER_BATCH: usize = 0x10000; -pub(crate) struct RendererD3D9 where D: Device { +pub(crate) struct RendererD3D9 +where + D: Device, +{ // Basic data programs: ProgramsD3D9, quads_vertex_indices_buffer_id: Option, @@ -54,17 +57,23 @@ pub(crate) struct RendererD3D9 where D: Device { dest_blend_framebuffer_id: FramebufferID, } -impl RendererD3D9 where D: Device { - pub(crate) fn new(core: &mut RendererCore, resources: &dyn ResourceLoader) - -> RendererD3D9 { +impl RendererD3D9 +where + D: Device, +{ + pub(crate) fn new( + core: &mut RendererCore, + resources: &dyn ResourceLoader, + ) -> RendererD3D9 { let programs = ProgramsD3D9::new(&core.device, resources); let window_size = core.options.dest.window_size(&core.device); - let dest_blend_framebuffer_id = - core.allocator.allocate_framebuffer(&core.device, - window_size, - TextureFormat::RGBA8, - FramebufferTag("DestBlendD3D9")); + let dest_blend_framebuffer_id = core.allocator.allocate_framebuffer( + &core.device, + window_size, + TextureFormat::RGBA8, + FramebufferTag("DestBlendD3D9"), + ); RendererD3D9 { programs, @@ -78,43 +87,57 @@ impl RendererD3D9 where D: Device { } } - pub(crate) fn upload_and_draw_tiles(&mut self, - core: &mut RendererCore, - batch: &DrawTileBatchD3D9) { + pub(crate) fn upload_and_draw_tiles( + &mut self, + core: &mut RendererCore, + batch: &DrawTileBatchD3D9, + ) { if !batch.clips.is_empty() { let clip_buffer_info = self.upload_clip_tiles(core, &batch.clips); self.clip_tiles(core, &clip_buffer_info); - core.allocator.free_general_buffer(clip_buffer_info.clip_buffer_id); + core.allocator + .free_general_buffer(clip_buffer_info.clip_buffer_id); } let tile_buffer = self.upload_tiles(core, &batch.tiles); let z_buffer_texture_id = self.upload_z_buffer(core, &batch.z_buffer_data); - self.draw_tiles(core, - batch.tiles.len() as u32, - tile_buffer.tile_vertex_buffer_id, - batch.color_texture, - batch.blend_mode, - z_buffer_texture_id); + self.draw_tiles( + core, + batch.tiles.len() as u32, + tile_buffer.tile_vertex_buffer_id, + batch.color_texture, + batch.blend_mode, + z_buffer_texture_id, + ); core.allocator.free_texture(z_buffer_texture_id); - core.allocator.free_general_buffer(tile_buffer.tile_vertex_buffer_id); + core.allocator + .free_general_buffer(tile_buffer.tile_vertex_buffer_id); } - fn upload_tiles(&mut self, core: &mut RendererCore, tiles: &[TileObjectPrimitive]) - -> TileBufferD3D9 { - let tile_vertex_buffer_id = - core.allocator.allocate_general_buffer::(&core.device, - tiles.len() as u64, - BufferTag("TileD3D9")); + fn upload_tiles( + &mut self, + core: &mut RendererCore, + tiles: &[TileObjectPrimitive], + ) -> TileBufferD3D9 { + let tile_vertex_buffer_id = core + .allocator + .allocate_general_buffer::( + &core.device, + tiles.len() as u64, + BufferTag("TileD3D9"), + ); let tile_vertex_buffer = &core.allocator.get_general_buffer(tile_vertex_buffer_id); - core.device.upload_to_buffer(tile_vertex_buffer, 0, tiles, BufferTarget::Vertex); + core.device + .upload_to_buffer(tile_vertex_buffer, 0, tiles, BufferTarget::Vertex); self.ensure_index_buffer(core, tiles.len()); - TileBufferD3D9 { tile_vertex_buffer_id } + TileBufferD3D9 { + tile_vertex_buffer_id, + } } - fn ensure_index_buffer(&mut self, core: &mut RendererCore, mut length: usize) { length = length.next_power_of_two(); if self.quads_vertex_indices_length >= length { @@ -125,24 +148,33 @@ impl RendererD3D9 where D: Device { 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, + index * 4 + 0, + index * 4 + 1, + index * 4 + 2, + index * 4 + 1, + index * 4 + 3, + index * 4 + 2, ]); } if let Some(quads_vertex_indices_buffer_id) = self.quads_vertex_indices_buffer_id.take() { - core.allocator.free_index_buffer(quads_vertex_indices_buffer_id); + core.allocator + .free_index_buffer(quads_vertex_indices_buffer_id); } - let quads_vertex_indices_buffer_id = - core.allocator.allocate_index_buffer::(&core.device, - indices.len() as u64, - BufferTag("QuadsVertexIndicesD3D9")); - let quads_vertex_indices_buffer = - core.allocator.get_index_buffer(quads_vertex_indices_buffer_id); - core.device.upload_to_buffer(quads_vertex_indices_buffer, - 0, - &indices, - BufferTarget::Index); + let quads_vertex_indices_buffer_id = core.allocator.allocate_index_buffer::( + &core.device, + indices.len() as u64, + BufferTag("QuadsVertexIndicesD3D9"), + ); + let quads_vertex_indices_buffer = core + .allocator + .get_index_buffer(quads_vertex_indices_buffer_id); + core.device.upload_to_buffer( + quads_vertex_indices_buffer, + 0, + &indices, + BufferTarget::Index, + ); self.quads_vertex_indices_buffer_id = Some(quads_vertex_indices_buffer_id); self.quads_vertex_indices_length = length; } @@ -179,221 +211,305 @@ impl RendererD3D9 where D: Device { } let fill_storage_info = self.upload_buffered_fills(core); - self.draw_fills(core, fill_storage_info.fill_buffer_id, fill_storage_info.fill_count); - core.allocator.free_general_buffer(fill_storage_info.fill_buffer_id); + self.draw_fills( + core, + fill_storage_info.fill_buffer_id, + fill_storage_info.fill_count, + ); + core.allocator + .free_general_buffer(fill_storage_info.fill_buffer_id); } fn upload_buffered_fills(&mut self, core: &mut RendererCore) -> FillBufferInfoD3D9 { let buffered_fills = &mut self.buffered_fills; debug_assert!(!buffered_fills.is_empty()); - let fill_buffer_id = core.allocator - .allocate_general_buffer::(&core.device, - MAX_FILLS_PER_BATCH as u64, - BufferTag("Fill")); + let fill_buffer_id = core.allocator.allocate_general_buffer::( + &core.device, + MAX_FILLS_PER_BATCH as u64, + BufferTag("Fill"), + ); let fill_vertex_buffer = core.allocator.get_general_buffer(fill_buffer_id); debug_assert!(buffered_fills.len() <= u32::MAX as usize); - core.device.upload_to_buffer(fill_vertex_buffer, 0, &buffered_fills, BufferTarget::Vertex); + core.device + .upload_to_buffer(fill_vertex_buffer, 0, &buffered_fills, BufferTarget::Vertex); let fill_count = buffered_fills.len() as u32; buffered_fills.clear(); - FillBufferInfoD3D9 { fill_buffer_id, fill_count } + FillBufferInfoD3D9 { + fill_buffer_id, + fill_count, + } } - fn draw_fills(&mut self, - core: &mut RendererCore, - fill_buffer_id: GeneralBufferID, - fill_count: u32) { + fn draw_fills( + &mut self, + core: &mut RendererCore, + fill_buffer_id: GeneralBufferID, + fill_count: u32, + ) { let fill_raster_program = &self.programs.fill_program; let fill_vertex_buffer = core.allocator.get_general_buffer(fill_buffer_id); - let quad_vertex_positions_buffer = - core.allocator.get_general_buffer(core.quad_vertex_positions_buffer_id); - let quad_vertex_indices_buffer = core.allocator - .get_index_buffer(core.quad_vertex_indices_buffer_id); + let quad_vertex_positions_buffer = core + .allocator + .get_general_buffer(core.quad_vertex_positions_buffer_id); + let quad_vertex_indices_buffer = core + .allocator + .get_index_buffer(core.quad_vertex_indices_buffer_id); let area_lut_texture = core.allocator.get_texture(core.area_lut_texture_id); let mask_viewport = self.mask_viewport(core); - let mask_storage = core.mask_storage.as_ref().expect("Where's the mask storage?"); + let mask_storage = core + .mask_storage + .as_ref() + .expect("Where's the mask storage?"); let mask_framebuffer_id = mask_storage.framebuffer_id; let mask_framebuffer = core.allocator.get_framebuffer(mask_framebuffer_id); - let fill_vertex_array = FillVertexArrayD3D9::new(&core.device, - fill_raster_program, - fill_vertex_buffer, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer); + let fill_vertex_array = FillVertexArrayD3D9::new( + &core.device, + fill_raster_program, + fill_vertex_buffer, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer, + ); let mut clear_color = None; - if !core.framebuffer_flags.contains(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY) { + if !core + .framebuffer_flags + .contains(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY) + { clear_color = Some(ColorF::default()); }; - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); - core.device.draw_elements_instanced(6, fill_count, &RenderState { - target: &RenderTarget::Framebuffer(mask_framebuffer), - program: &fill_raster_program.program, - vertex_array: &fill_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[(&fill_raster_program.area_lut_texture, area_lut_texture)], - uniforms: &[ - (&fill_raster_program.framebuffer_size_uniform, - UniformData::Vec2(mask_viewport.size().to_f32().0)), - (&fill_raster_program.tile_size_uniform, - UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))), - ], - images: &[], - storage_buffers: &[], - 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() + core.device.draw_elements_instanced( + 6, + fill_count, + &RenderState { + target: &RenderTarget::Framebuffer(mask_framebuffer), + program: &fill_raster_program.program, + vertex_array: &fill_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[(&fill_raster_program.area_lut_texture, area_lut_texture)], + uniforms: &[ + ( + &fill_raster_program.framebuffer_size_uniform, + UniformData::Vec2(mask_viewport.size().to_f32().0), + ), + ( + &fill_raster_program.tile_size_uniform, + UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32)), + ), + ], + images: &[], + storage_buffers: &[], + 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() + }, }, - }); + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Fill, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Fill, timer_query); - core.framebuffer_flags.insert(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY); + core.framebuffer_flags + .insert(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY); } fn clip_tiles(&mut self, core: &mut RendererCore, clip_buffer_info: &ClipBufferInfo) { // Allocate temp mask framebuffer. - let mask_temp_framebuffer_id = - core.allocator.allocate_framebuffer(&core.device, - self.mask_viewport(core).size(), - core.mask_texture_format(), - FramebufferTag("TempClipMaskD3D9")); + let mask_temp_framebuffer_id = core.allocator.allocate_framebuffer( + &core.device, + self.mask_viewport(core).size(), + core.mask_texture_format(), + FramebufferTag("TempClipMaskD3D9"), + ); let mask_temp_framebuffer = core.allocator.get_framebuffer(mask_temp_framebuffer_id); - let mask_storage = core.mask_storage.as_ref().expect("Where's the mask storage?"); + let mask_storage = core + .mask_storage + .as_ref() + .expect("Where's the mask storage?"); let mask_framebuffer_id = mask_storage.framebuffer_id; let mask_framebuffer = core.allocator.get_framebuffer(mask_framebuffer_id); let mask_texture = core.device.framebuffer_texture(mask_framebuffer); let mask_texture_size = core.device.texture_size(&mask_texture); - let clip_vertex_buffer = core.allocator - .get_general_buffer(clip_buffer_info.clip_buffer_id); - let quad_vertex_positions_buffer = - core.allocator.get_general_buffer(core.quad_vertex_positions_buffer_id); - let quad_vertex_indices_buffer = core.allocator - .get_index_buffer(core.quad_vertex_indices_buffer_id); + let clip_vertex_buffer = core + .allocator + .get_general_buffer(clip_buffer_info.clip_buffer_id); + let quad_vertex_positions_buffer = core + .allocator + .get_general_buffer(core.quad_vertex_positions_buffer_id); + let quad_vertex_indices_buffer = core + .allocator + .get_index_buffer(core.quad_vertex_indices_buffer_id); - let tile_clip_copy_vertex_array = - ClipTileCopyVertexArrayD3D9::new(&core.device, - &self.programs.tile_clip_copy_program, - clip_vertex_buffer, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer); - let tile_clip_combine_vertex_array = - ClipTileCombineVertexArrayD3D9::new(&core.device, - &self.programs.tile_clip_combine_program, - clip_vertex_buffer, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer); + let tile_clip_copy_vertex_array = ClipTileCopyVertexArrayD3D9::new( + &core.device, + &self.programs.tile_clip_copy_program, + clip_vertex_buffer, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer, + ); + let tile_clip_combine_vertex_array = ClipTileCombineVertexArrayD3D9::new( + &core.device, + &self.programs.tile_clip_combine_program, + clip_vertex_buffer, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer, + ); - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); // Copy out tiles. // // TODO(pcwalton): Don't do this on GL4. - core.device.draw_elements_instanced(6, clip_buffer_info.clip_count * 2, &RenderState { - target: &RenderTarget::Framebuffer(mask_temp_framebuffer), - program: &self.programs.tile_clip_copy_program.program, - vertex_array: &tile_clip_copy_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[ - (&self.programs.tile_clip_copy_program.src_texture, - core.device.framebuffer_texture(mask_framebuffer)), - ], - images: &[], - uniforms: &[ - (&self.programs.tile_clip_copy_program.framebuffer_size_uniform, - UniformData::Vec2(mask_texture_size.to_f32().0)), - ], - storage_buffers: &[], - viewport: RectI::new(Vector2I::zero(), mask_texture_size), - options: RenderOptions::default(), - }); + core.device.draw_elements_instanced( + 6, + clip_buffer_info.clip_count * 2, + &RenderState { + target: &RenderTarget::Framebuffer(mask_temp_framebuffer), + program: &self.programs.tile_clip_copy_program.program, + vertex_array: &tile_clip_copy_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[( + &self.programs.tile_clip_copy_program.src_texture, + core.device.framebuffer_texture(mask_framebuffer), + )], + images: &[], + uniforms: &[( + &self + .programs + .tile_clip_copy_program + .framebuffer_size_uniform, + UniformData::Vec2(mask_texture_size.to_f32().0), + )], + storage_buffers: &[], + viewport: RectI::new(Vector2I::zero(), mask_texture_size), + options: RenderOptions::default(), + }, + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Other, timer_query); - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Other, timer_query); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); // Combine clip tiles. - core.device.draw_elements_instanced(6, clip_buffer_info.clip_count, &RenderState { - target: &RenderTarget::Framebuffer(mask_framebuffer), - program: &self.programs.tile_clip_combine_program.program, - vertex_array: &tile_clip_combine_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[ - (&self.programs.tile_clip_combine_program.src_texture, - core.device.framebuffer_texture(&mask_temp_framebuffer)), - ], - images: &[], - uniforms: &[ - (&self.programs.tile_clip_combine_program.framebuffer_size_uniform, - UniformData::Vec2(mask_texture_size.to_f32().0)), - ], - storage_buffers: &[], - viewport: RectI::new(Vector2I::zero(), mask_texture_size), - options: RenderOptions::default(), - }); + core.device.draw_elements_instanced( + 6, + clip_buffer_info.clip_count, + &RenderState { + target: &RenderTarget::Framebuffer(mask_framebuffer), + program: &self.programs.tile_clip_combine_program.program, + vertex_array: &tile_clip_combine_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[( + &self.programs.tile_clip_combine_program.src_texture, + core.device.framebuffer_texture(&mask_temp_framebuffer), + )], + images: &[], + uniforms: &[( + &self + .programs + .tile_clip_combine_program + .framebuffer_size_uniform, + UniformData::Vec2(mask_texture_size.to_f32().0), + )], + storage_buffers: &[], + viewport: RectI::new(Vector2I::zero(), mask_texture_size), + options: RenderOptions::default(), + }, + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Other, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Other, timer_query); core.allocator.free_framebuffer(mask_temp_framebuffer_id); } - fn upload_z_buffer(&mut self, core: &mut RendererCore, z_buffer_map: &DenseTileMap) - -> TextureID { - let z_buffer_texture_id = core.allocator.allocate_texture(&core.device, - z_buffer_map.rect.size(), - TextureFormat::RGBA8, - TextureTag("ZBufferD3D9")); + fn upload_z_buffer( + &mut self, + core: &mut RendererCore, + z_buffer_map: &DenseTileMap, + ) -> TextureID { + let z_buffer_texture_id = core.allocator.allocate_texture( + &core.device, + z_buffer_map.rect.size(), + TextureFormat::RGBA8, + TextureTag("ZBufferD3D9"), + ); let z_buffer_texture = core.allocator.get_texture(z_buffer_texture_id); debug_assert_eq!(z_buffer_map.rect.origin(), Vector2I::default()); let z_data: &[u8] = z_buffer_map.data.as_byte_slice(); - core.device.upload_to_texture(z_buffer_texture, - z_buffer_map.rect, - TextureDataRef::U8(&z_data)); + core.device.upload_to_texture( + z_buffer_texture, + z_buffer_map.rect, + TextureDataRef::U8(&z_data), + ); z_buffer_texture_id } // Uploads clip tiles from CPU to GPU. fn upload_clip_tiles(&mut self, core: &mut RendererCore, clips: &[Clip]) -> ClipBufferInfo { - let clip_buffer_id = core.allocator.allocate_general_buffer::(&core.device, - clips.len() as u64, - BufferTag("ClipD3D9")); + let clip_buffer_id = core.allocator.allocate_general_buffer::( + &core.device, + clips.len() as u64, + BufferTag("ClipD3D9"), + ); let clip_buffer = core.allocator.get_general_buffer(clip_buffer_id); - core.device.upload_to_buffer(clip_buffer, 0, clips, BufferTarget::Vertex); - ClipBufferInfo { clip_buffer_id, clip_count: clips.len() as u32 } + core.device + .upload_to_buffer(clip_buffer, 0, clips, BufferTarget::Vertex); + ClipBufferInfo { + clip_buffer_id, + clip_count: clips.len() as u32, + } } - fn draw_tiles(&mut self, - core: &mut RendererCore, - tile_count: u32, - tile_vertex_buffer_id: GeneralBufferID, - color_texture_0: Option, - blend_mode: BlendMode, - z_buffer_texture_id: TextureID) { + fn draw_tiles( + &mut self, + core: &mut RendererCore, + tile_count: u32, + tile_vertex_buffer_id: GeneralBufferID, + color_texture_0: Option, + blend_mode: BlendMode, + z_buffer_texture_id: TextureID, + ) { // TODO(pcwalton): Disable blend for solid tiles. if tile_count == 0 { @@ -410,79 +526,112 @@ impl RendererD3D9 where D: Device { let clear_color = core.clear_color_for_draw_operation(); let draw_viewport = core.draw_viewport(); - let timer_query = core.timer_query_cache.start_timing_draw_call(&core.device, - &core.options); + let timer_query = core + .timer_query_cache + .start_timing_draw_call(&core.device, &core.options); let tile_raster_program = &self.programs.tile_program; let tile_vertex_buffer = core.allocator.get_general_buffer(tile_vertex_buffer_id); - let quad_vertex_positions_buffer = - core.allocator.get_general_buffer(core.quad_vertex_positions_buffer_id); - let quad_vertex_indices_buffer = core.allocator - .get_index_buffer(core.quad_vertex_indices_buffer_id); - let dest_blend_framebuffer = core.allocator - .get_framebuffer(self.dest_blend_framebuffer_id); + let quad_vertex_positions_buffer = core + .allocator + .get_general_buffer(core.quad_vertex_positions_buffer_id); + let quad_vertex_indices_buffer = core + .allocator + .get_index_buffer(core.quad_vertex_indices_buffer_id); + let dest_blend_framebuffer = core + .allocator + .get_framebuffer(self.dest_blend_framebuffer_id); let (mut textures, mut uniforms) = (vec![], vec![]); - core.set_uniforms_for_drawing_tiles(&tile_raster_program.common, - &mut textures, - &mut uniforms, - color_texture_0); + core.set_uniforms_for_drawing_tiles( + &tile_raster_program.common, + &mut textures, + &mut uniforms, + color_texture_0, + ); - uniforms.push((&tile_raster_program.transform_uniform, - UniformData::Mat4(self.tile_transform(core).to_columns()))); - textures.push((&tile_raster_program.dest_texture, - core.device.framebuffer_texture(dest_blend_framebuffer))); + uniforms.push(( + &tile_raster_program.transform_uniform, + UniformData::Mat4(self.tile_transform(core).to_columns()), + )); + textures.push(( + &tile_raster_program.dest_texture, + core.device.framebuffer_texture(dest_blend_framebuffer), + )); let z_buffer_texture = core.allocator.get_texture(z_buffer_texture_id); - textures.push((&tile_raster_program.common.z_buffer_texture, z_buffer_texture)); - uniforms.push((&tile_raster_program.common.z_buffer_texture_size_uniform, - UniformData::IVec2(core.device.texture_size(z_buffer_texture).0))); + textures.push(( + &tile_raster_program.common.z_buffer_texture, + z_buffer_texture, + )); + uniforms.push(( + &tile_raster_program.common.z_buffer_texture_size_uniform, + UniformData::IVec2(core.device.texture_size(z_buffer_texture).0), + )); - let tile_vertex_array = TileVertexArrayD3D9::new(&core.device, - &self.programs.tile_program, - tile_vertex_buffer, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer); + let tile_vertex_array = TileVertexArrayD3D9::new( + &core.device, + &self.programs.tile_program, + tile_vertex_buffer, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer, + ); - core.device.draw_elements_instanced(6, tile_count, &RenderState { - target: &core.draw_render_target(), - program: &tile_raster_program.common.program, - vertex_array: &tile_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &textures, - images: &[], - storage_buffers: &[], - uniforms: &uniforms, - viewport: draw_viewport, - options: RenderOptions { - blend: blend_mode.to_blend_state(), - stencil: self.stencil_state(core), - clear_ops: ClearOps { color: clear_color, ..ClearOps::default() }, - ..RenderOptions::default() + core.device.draw_elements_instanced( + 6, + tile_count, + &RenderState { + target: &core.draw_render_target(), + program: &tile_raster_program.common.program, + vertex_array: &tile_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &textures, + images: &[], + storage_buffers: &[], + uniforms: &uniforms, + viewport: draw_viewport, + options: RenderOptions { + blend: blend_mode.to_blend_state(), + stencil: self.stencil_state(core), + clear_ops: ClearOps { + color: clear_color, + ..ClearOps::default() + }, + ..RenderOptions::default() + }, }, - }); + ); core.stats.drawcall_count += 1; core.finish_timing_draw_call(&timer_query); - core.current_timer.as_mut().unwrap().push_query(TimeCategory::Composite, timer_query); + core.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Composite, timer_query); core.preserve_draw_framebuffer(); } - fn copy_alpha_tiles_to_dest_blend_texture(&mut self, - core: &mut RendererCore, - tile_count: u32, - vertex_buffer_id: GeneralBufferID) { + fn copy_alpha_tiles_to_dest_blend_texture( + &mut self, + core: &mut RendererCore, + tile_count: u32, + vertex_buffer_id: GeneralBufferID, + ) { let draw_viewport = core.draw_viewport(); let mut textures = vec![]; let mut uniforms = vec![ - (&self.programs.tile_copy_program.transform_uniform, - UniformData::Mat4(self.tile_transform(core).to_columns())), - (&self.programs.tile_copy_program.tile_size_uniform, - UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))), + ( + &self.programs.tile_copy_program.transform_uniform, + UniformData::Mat4(self.tile_transform(core).to_columns()), + ), + ( + &self.programs.tile_copy_program.tile_size_uniform, + UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32)), + ), ]; let draw_framebuffer = match core.draw_render_target() { @@ -492,41 +641,51 @@ impl RendererD3D9 where D: Device { let draw_texture = core.device.framebuffer_texture(&draw_framebuffer); textures.push((&self.programs.tile_copy_program.src_texture, draw_texture)); - uniforms.push((&self.programs.tile_copy_program.framebuffer_size_uniform, - UniformData::Vec2(draw_viewport.size().to_f32().0))); + uniforms.push(( + &self.programs.tile_copy_program.framebuffer_size_uniform, + UniformData::Vec2(draw_viewport.size().to_f32().0), + )); - let quads_vertex_indices_buffer_id = self.quads_vertex_indices_buffer_id - .expect("Where's the quads vertex buffer?"); - let quads_vertex_indices_buffer = core.allocator - .get_index_buffer(quads_vertex_indices_buffer_id); + let quads_vertex_indices_buffer_id = self + .quads_vertex_indices_buffer_id + .expect("Where's the quads vertex buffer?"); + let quads_vertex_indices_buffer = core + .allocator + .get_index_buffer(quads_vertex_indices_buffer_id); let vertex_buffer = core.allocator.get_general_buffer(vertex_buffer_id); - let tile_copy_vertex_array = CopyTileVertexArray::new(&core.device, - &self.programs.tile_copy_program, - vertex_buffer, - quads_vertex_indices_buffer); + let tile_copy_vertex_array = CopyTileVertexArray::new( + &core.device, + &self.programs.tile_copy_program, + vertex_buffer, + quads_vertex_indices_buffer, + ); - let dest_blend_framebuffer = core.allocator - .get_framebuffer(self.dest_blend_framebuffer_id); + let dest_blend_framebuffer = core + .allocator + .get_framebuffer(self.dest_blend_framebuffer_id); - core.device.draw_elements(tile_count * 6, &RenderState { - target: &RenderTarget::Framebuffer(dest_blend_framebuffer), - program: &self.programs.tile_copy_program.program, - vertex_array: &tile_copy_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &textures, - images: &[], - storage_buffers: &[], - uniforms: &uniforms, - viewport: draw_viewport, - options: RenderOptions { - clear_ops: ClearOps { - color: Some(ColorF::new(1.0, 0.0, 0.0, 1.0)), - ..ClearOps::default() + core.device.draw_elements( + tile_count * 6, + &RenderState { + target: &RenderTarget::Framebuffer(dest_blend_framebuffer), + program: &self.programs.tile_copy_program.program, + vertex_array: &tile_copy_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &textures, + images: &[], + storage_buffers: &[], + 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() }, - ..RenderOptions::default() }, - }); + ); core.stats.drawcall_count += 1; } diff --git a/renderer/src/gpu/d3d9/shaders.rs b/renderer/src/gpu/d3d9/shaders.rs index 7e560ea0..ef919491 100644 --- a/renderer/src/gpu/d3d9/shaders.rs +++ b/renderer/src/gpu/d3d9/shaders.rs @@ -10,313 +10,478 @@ //! Shaders and vertex specifications for the Direct3D 9-level renderer. -use crate::gpu::shaders::{TILE_INSTANCE_SIZE, TileProgramCommon}; +use crate::gpu::shaders::{TileProgramCommon, TILE_INSTANCE_SIZE}; use pathfinder_gpu::{BufferTarget, Device, VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; use pathfinder_resources::ResourceLoader; const FILL_INSTANCE_SIZE: usize = 12; const CLIP_TILE_INSTANCE_SIZE: usize = 16; -pub(crate) struct FillVertexArrayD3D9 where D: Device { +pub(crate) struct FillVertexArrayD3D9 +where + D: Device, +{ pub(crate) vertex_array: D::VertexArray, } -impl FillVertexArrayD3D9 where D: Device { - pub(crate) fn new(device: &D, - fill_program: &FillProgramD3D9, - vertex_buffer: &D::Buffer, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> FillVertexArrayD3D9 { +impl FillVertexArrayD3D9 +where + D: Device, +{ + pub(crate) fn new( + device: &D, + fill_program: &FillProgramD3D9, + vertex_buffer: &D::Buffer, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer, + ) -> FillVertexArrayD3D9 { let vertex_array = device.create_vertex_array(); - let tess_coord_attr = device.get_vertex_attr(&fill_program.program, "TessCoord").unwrap(); - let line_segment_attr = device.get_vertex_attr(&fill_program.program, "LineSegment") - .unwrap(); - let tile_index_attr = device.get_vertex_attr(&fill_program.program, "TileIndex").unwrap(); + let tess_coord_attr = device + .get_vertex_attr(&fill_program.program, "TessCoord") + .unwrap(); + let line_segment_attr = device + .get_vertex_attr(&fill_program.program, "LineSegment") + .unwrap(); + let tile_index_attr = device + .get_vertex_attr(&fill_program.program, "TileIndex") + .unwrap(); - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tess_coord_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); + device.bind_buffer( + &vertex_array, + quad_vertex_positions_buffer, + BufferTarget::Vertex, + ); + device.configure_vertex_attr( + &vertex_array, + &tess_coord_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }, + ); device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &line_segment_attr, &VertexAttrDescriptor { - size: 4, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U16, - stride: FILL_INSTANCE_SIZE, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I32, - stride: FILL_INSTANCE_SIZE, - offset: 8, - divisor: 1, - buffer_index: 1, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + device.configure_vertex_attr( + &vertex_array, + &line_segment_attr, + &VertexAttrDescriptor { + size: 4, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U16, + stride: FILL_INSTANCE_SIZE, + offset: 0, + divisor: 1, + buffer_index: 1, + }, + ); + device.configure_vertex_attr( + &vertex_array, + &tile_index_attr, + &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: FILL_INSTANCE_SIZE, + offset: 8, + divisor: 1, + buffer_index: 1, + }, + ); + device.bind_buffer( + &vertex_array, + quad_vertex_indices_buffer, + BufferTarget::Index, + ); FillVertexArrayD3D9 { vertex_array } } } -pub(crate) struct TileVertexArrayD3D9 where D: Device { +pub(crate) struct TileVertexArrayD3D9 +where + D: Device, +{ pub(crate) vertex_array: D::VertexArray, } -impl TileVertexArrayD3D9 where D: Device { - pub(crate) fn new(device: &D, - tile_program: &TileProgramD3D9, - tile_vertex_buffer: &D::Buffer, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> TileVertexArrayD3D9 { +impl TileVertexArrayD3D9 +where + D: Device, +{ + pub(crate) fn new( + device: &D, + tile_program: &TileProgramD3D9, + tile_vertex_buffer: &D::Buffer, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer, + ) -> TileVertexArrayD3D9 { let vertex_array = device.create_vertex_array(); - let tile_offset_attr = - device.get_vertex_attr(&tile_program.common.program, "TileOffset").unwrap(); - let tile_origin_attr = - device.get_vertex_attr(&tile_program.common.program, "TileOrigin").unwrap(); - let mask_0_tex_coord_attr = - device.get_vertex_attr(&tile_program.common.program, "MaskTexCoord0").unwrap(); - let ctrl_backdrop_attr = - device.get_vertex_attr(&tile_program.common.program, "CtrlBackdrop").unwrap(); - let color_attr = device.get_vertex_attr(&tile_program.common.program, "Color").unwrap(); - let path_index_attr = device.get_vertex_attr(&tile_program.common.program, "PathIndex") - .unwrap(); + let tile_offset_attr = device + .get_vertex_attr(&tile_program.common.program, "TileOffset") + .unwrap(); + let tile_origin_attr = device + .get_vertex_attr(&tile_program.common.program, "TileOrigin") + .unwrap(); + let mask_0_tex_coord_attr = device + .get_vertex_attr(&tile_program.common.program, "MaskTexCoord0") + .unwrap(); + let ctrl_backdrop_attr = device + .get_vertex_attr(&tile_program.common.program, "CtrlBackdrop") + .unwrap(); + let color_attr = device + .get_vertex_attr(&tile_program.common.program, "Color") + .unwrap(); + let path_index_attr = device + .get_vertex_attr(&tile_program.common.program, "PathIndex") + .unwrap(); - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); + device.bind_buffer( + &vertex_array, + quad_vertex_positions_buffer, + BufferTarget::Vertex, + ); + device.configure_vertex_attr( + &vertex_array, + &tile_offset_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }, + ); device.bind_buffer(&vertex_array, tile_vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_origin_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &mask_0_tex_coord_attr, &VertexAttrDescriptor { - size: 4, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: TILE_INSTANCE_SIZE, - offset: 4, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &path_index_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I32, - stride: TILE_INSTANCE_SIZE, - offset: 8, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &color_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 12, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &ctrl_backdrop_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I8, - stride: TILE_INSTANCE_SIZE, - offset: 14, - divisor: 1, - buffer_index: 1, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + device.configure_vertex_attr( + &vertex_array, + &tile_origin_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: TILE_INSTANCE_SIZE, + offset: 0, + divisor: 1, + buffer_index: 1, + }, + ); + device.configure_vertex_attr( + &vertex_array, + &mask_0_tex_coord_attr, + &VertexAttrDescriptor { + size: 4, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U8, + stride: TILE_INSTANCE_SIZE, + offset: 4, + divisor: 1, + buffer_index: 1, + }, + ); + device.configure_vertex_attr( + &vertex_array, + &path_index_attr, + &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: TILE_INSTANCE_SIZE, + offset: 8, + divisor: 1, + buffer_index: 1, + }, + ); + device.configure_vertex_attr( + &vertex_array, + &color_attr, + &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: TILE_INSTANCE_SIZE, + offset: 12, + divisor: 1, + buffer_index: 1, + }, + ); + device.configure_vertex_attr( + &vertex_array, + &ctrl_backdrop_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I8, + stride: TILE_INSTANCE_SIZE, + offset: 14, + divisor: 1, + buffer_index: 1, + }, + ); + device.bind_buffer( + &vertex_array, + quad_vertex_indices_buffer, + BufferTarget::Index, + ); TileVertexArrayD3D9 { vertex_array } } } -pub(crate) struct ClipTileCopyVertexArrayD3D9 where D: Device { +pub(crate) struct ClipTileCopyVertexArrayD3D9 +where + D: Device, +{ pub(crate) vertex_array: D::VertexArray, } -impl ClipTileCopyVertexArrayD3D9 where D: Device { - pub(crate) fn new(device: &D, - clip_tile_copy_program: &ClipTileCopyProgramD3D9, - vertex_buffer: &D::Buffer, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> ClipTileCopyVertexArrayD3D9 { +impl ClipTileCopyVertexArrayD3D9 +where + D: Device, +{ + pub(crate) fn new( + device: &D, + clip_tile_copy_program: &ClipTileCopyProgramD3D9, + vertex_buffer: &D::Buffer, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer, + ) -> ClipTileCopyVertexArrayD3D9 { let vertex_array = device.create_vertex_array(); - let tile_offset_attr = - device.get_vertex_attr(&clip_tile_copy_program.program, "TileOffset").unwrap(); - let tile_index_attr = - device.get_vertex_attr(&clip_tile_copy_program.program, "TileIndex").unwrap(); + let tile_offset_attr = device + .get_vertex_attr(&clip_tile_copy_program.program, "TileOffset") + .unwrap(); + let tile_index_attr = device + .get_vertex_attr(&clip_tile_copy_program.program, "TileIndex") + .unwrap(); - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); + device.bind_buffer( + &vertex_array, + quad_vertex_positions_buffer, + BufferTarget::Vertex, + ); + device.configure_vertex_attr( + &vertex_array, + &tile_offset_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }, + ); device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I32, - stride: CLIP_TILE_INSTANCE_SIZE / 2, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + device.configure_vertex_attr( + &vertex_array, + &tile_index_attr, + &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE / 2, + offset: 0, + divisor: 1, + buffer_index: 1, + }, + ); + device.bind_buffer( + &vertex_array, + quad_vertex_indices_buffer, + BufferTarget::Index, + ); ClipTileCopyVertexArrayD3D9 { vertex_array } } } -pub(crate) struct ClipTileCombineVertexArrayD3D9 where D: Device { +pub(crate) struct ClipTileCombineVertexArrayD3D9 +where + D: Device, +{ pub(crate) vertex_array: D::VertexArray, } -impl ClipTileCombineVertexArrayD3D9 where D: Device { - pub(crate) fn new(device: &D, - clip_tile_combine_program: &ClipTileCombineProgramD3D9, - vertex_buffer: &D::Buffer, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> ClipTileCombineVertexArrayD3D9 { +impl ClipTileCombineVertexArrayD3D9 +where + D: Device, +{ + pub(crate) fn new( + device: &D, + clip_tile_combine_program: &ClipTileCombineProgramD3D9, + vertex_buffer: &D::Buffer, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer, + ) -> ClipTileCombineVertexArrayD3D9 { let vertex_array = device.create_vertex_array(); - let tile_offset_attr = - device.get_vertex_attr(&clip_tile_combine_program.program, "TileOffset").unwrap(); - let dest_tile_index_attr = - device.get_vertex_attr(&clip_tile_combine_program.program, "DestTileIndex").unwrap(); - let dest_backdrop_attr = - device.get_vertex_attr(&clip_tile_combine_program.program, "DestBackdrop").unwrap(); - let src_tile_index_attr = - device.get_vertex_attr(&clip_tile_combine_program.program, "SrcTileIndex").unwrap(); - let src_backdrop_attr = - device.get_vertex_attr(&clip_tile_combine_program.program, "SrcBackdrop").unwrap(); + let tile_offset_attr = device + .get_vertex_attr(&clip_tile_combine_program.program, "TileOffset") + .unwrap(); + let dest_tile_index_attr = device + .get_vertex_attr(&clip_tile_combine_program.program, "DestTileIndex") + .unwrap(); + let dest_backdrop_attr = device + .get_vertex_attr(&clip_tile_combine_program.program, "DestBackdrop") + .unwrap(); + let src_tile_index_attr = device + .get_vertex_attr(&clip_tile_combine_program.program, "SrcTileIndex") + .unwrap(); + let src_backdrop_attr = device + .get_vertex_attr(&clip_tile_combine_program.program, "SrcBackdrop") + .unwrap(); - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); + device.bind_buffer( + &vertex_array, + quad_vertex_positions_buffer, + BufferTarget::Vertex, + ); + device.configure_vertex_attr( + &vertex_array, + &tile_offset_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }, + ); device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &dest_tile_index_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I32, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &dest_backdrop_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I32, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 4, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &src_tile_index_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I32, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 8, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &src_backdrop_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I32, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 12, - divisor: 1, - buffer_index: 1, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + device.configure_vertex_attr( + &vertex_array, + &dest_tile_index_attr, + &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE, + offset: 0, + divisor: 1, + buffer_index: 1, + }, + ); + device.configure_vertex_attr( + &vertex_array, + &dest_backdrop_attr, + &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE, + offset: 4, + divisor: 1, + buffer_index: 1, + }, + ); + device.configure_vertex_attr( + &vertex_array, + &src_tile_index_attr, + &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE, + offset: 8, + divisor: 1, + buffer_index: 1, + }, + ); + device.configure_vertex_attr( + &vertex_array, + &src_backdrop_attr, + &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE, + offset: 12, + divisor: 1, + buffer_index: 1, + }, + ); + device.bind_buffer( + &vertex_array, + quad_vertex_indices_buffer, + BufferTarget::Index, + ); ClipTileCombineVertexArrayD3D9 { vertex_array } } } -pub(crate) struct CopyTileVertexArray where D: Device { +pub(crate) struct CopyTileVertexArray +where + D: Device, +{ pub(crate) vertex_array: D::VertexArray, } -impl CopyTileVertexArray where D: Device { - pub(crate) fn new(device: &D, - copy_tile_program: &CopyTileProgram, - copy_tile_vertex_buffer: &D::Buffer, - quads_vertex_indices_buffer: &D::Buffer) - -> CopyTileVertexArray { +impl CopyTileVertexArray +where + D: Device, +{ + pub(crate) 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 tile_position_attr = - device.get_vertex_attr(©_tile_program.program, "TilePosition").unwrap(); + let tile_position_attr = device + .get_vertex_attr(©_tile_program.program, "TilePosition") + .unwrap(); device.bind_buffer(&vertex_array, copy_tile_vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index); + device.configure_vertex_attr( + &vertex_array, + &tile_position_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: TILE_INSTANCE_SIZE, + offset: 0, + divisor: 0, + buffer_index: 0, + }, + ); + device.bind_buffer( + &vertex_array, + quads_vertex_indices_buffer, + BufferTarget::Index, + ); CopyTileVertexArray { vertex_array } } } -pub(crate) struct FillProgramD3D9 where D: Device { +pub(crate) struct FillProgramD3D9 +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) framebuffer_size_uniform: D::Uniform, pub(crate) tile_size_uniform: D::Uniform, pub(crate) area_lut_texture: D::TextureParameter, } -impl FillProgramD3D9 where D: Device { +impl FillProgramD3D9 +where + D: Device, +{ fn new(device: &D, resources: &dyn ResourceLoader) -> FillProgramD3D9 { let program = device.create_raster_program(resources, "d3d9/fill"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); @@ -331,54 +496,86 @@ impl FillProgramD3D9 where D: Device { } } -pub(crate) struct TileProgramD3D9 where D: Device { +pub(crate) struct TileProgramD3D9 +where + D: Device, +{ pub(crate) common: TileProgramCommon, pub(crate) dest_texture: D::TextureParameter, pub(crate) transform_uniform: D::Uniform, } -impl TileProgramD3D9 where D: Device { +impl TileProgramD3D9 +where + D: Device, +{ fn new(device: &D, resources: &dyn ResourceLoader) -> TileProgramD3D9 { let program = device.create_raster_program(resources, "d3d9/tile"); let dest_texture = device.get_texture_parameter(&program, "DestTexture"); let transform_uniform = device.get_uniform(&program, "Transform"); let common = TileProgramCommon::new(device, program); - TileProgramD3D9 { common, dest_texture, transform_uniform } + TileProgramD3D9 { + common, + dest_texture, + transform_uniform, + } } } -pub(crate) struct ClipTileCombineProgramD3D9 where D: Device { +pub(crate) struct ClipTileCombineProgramD3D9 +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) src_texture: D::TextureParameter, pub(crate) framebuffer_size_uniform: D::Uniform, } -impl ClipTileCombineProgramD3D9 where D: Device { - pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) - -> ClipTileCombineProgramD3D9 { +impl ClipTileCombineProgramD3D9 +where + D: Device, +{ + pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> ClipTileCombineProgramD3D9 { let program = device.create_raster_program(resources, "d3d9/tile_clip_combine"); let src_texture = device.get_texture_parameter(&program, "Src"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - ClipTileCombineProgramD3D9 { program, src_texture, framebuffer_size_uniform } + ClipTileCombineProgramD3D9 { + program, + src_texture, + framebuffer_size_uniform, + } } } -pub(crate) struct ClipTileCopyProgramD3D9 where D: Device { +pub(crate) struct ClipTileCopyProgramD3D9 +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) src_texture: D::TextureParameter, pub(crate) framebuffer_size_uniform: D::Uniform, } -impl ClipTileCopyProgramD3D9 where D: Device { +impl ClipTileCopyProgramD3D9 +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> ClipTileCopyProgramD3D9 { let program = device.create_raster_program(resources, "d3d9/tile_clip_copy"); let src_texture = device.get_texture_parameter(&program, "Src"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - ClipTileCopyProgramD3D9 { program, src_texture, framebuffer_size_uniform } + ClipTileCopyProgramD3D9 { + program, + src_texture, + framebuffer_size_uniform, + } } } -pub(crate) struct CopyTileProgram where D: Device { +pub(crate) struct CopyTileProgram +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) transform_uniform: D::Uniform, pub(crate) tile_size_uniform: D::Uniform, @@ -386,7 +583,10 @@ pub(crate) struct CopyTileProgram where D: Device { pub(crate) src_texture: D::TextureParameter, } -impl CopyTileProgram where D: Device { +impl CopyTileProgram +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> CopyTileProgram { let program = device.create_raster_program(resources, "d3d9/tile_copy"); let transform_uniform = device.get_uniform(&program, "Transform"); @@ -403,7 +603,10 @@ impl CopyTileProgram where D: Device { } } -pub(crate) struct ProgramsD3D9 where D: Device { +pub(crate) struct ProgramsD3D9 +where + D: Device, +{ pub(crate) fill_program: FillProgramD3D9, pub(crate) tile_program: TileProgramD3D9, pub(crate) tile_clip_copy_program: ClipTileCopyProgramD3D9, @@ -411,7 +614,10 @@ pub(crate) struct ProgramsD3D9 where D: Device { pub(crate) tile_copy_program: CopyTileProgram, } -impl ProgramsD3D9 where D: Device { +impl ProgramsD3D9 +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> ProgramsD3D9 { ProgramsD3D9 { fill_program: FillProgramD3D9::new(device, resources), diff --git a/renderer/src/gpu/debug.rs b/renderer/src/gpu/debug.rs index e9f3b5d5..0e538f31 100644 --- a/renderer/src/gpu/debug.rs +++ b/renderer/src/gpu/debug.rs @@ -18,11 +18,11 @@ use crate::gpu::options::RendererLevel; use crate::gpu::perf::{RenderStats, RenderTime}; use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::{Vector2I, vec2i}; -use pathfinder_gpu::Device; +use pathfinder_geometry::vector::{vec2i, Vector2I}; use pathfinder_gpu::allocator::GPUMemoryAllocator; +use pathfinder_gpu::Device; use pathfinder_resources::ResourceLoader; -use pathfinder_ui::{FONT_ASCENT, LINE_HEIGHT, PADDING, UIPresenter, WINDOW_COLOR}; +use pathfinder_ui::{UIPresenter, FONT_ASCENT, LINE_HEIGHT, PADDING, WINDOW_COLOR}; use std::collections::VecDeque; use std::ops::{Add, Div}; use std::time::Duration; @@ -40,9 +40,12 @@ const INFO_WINDOW_WIDTH: i32 = 425; const INFO_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 2 + PADDING + 2; /// Manages the debug UI. -pub struct DebugUIPresenter where D: Device { +pub struct DebugUIPresenter +where + D: Device, +{ /// The general UI presenter object. - /// + /// /// You can use this to draw your own application-specific debug widgets. pub ui_presenter: UIPresenter, @@ -53,12 +56,16 @@ pub struct DebugUIPresenter where D: Device { renderer_level: RendererLevel, } -impl DebugUIPresenter where D: Device { - pub(crate) fn new(device: &D, - resources: &dyn ResourceLoader, - framebuffer_size: Vector2I, - renderer_level: RendererLevel) - -> DebugUIPresenter { +impl DebugUIPresenter +where + D: Device, +{ + pub(crate) fn new( + device: &D, + resources: &dyn ResourceLoader, + framebuffer_size: Vector2I, + renderer_level: RendererLevel, + ) -> DebugUIPresenter { let ui_presenter = UIPresenter::new(device, resources, framebuffer_size); DebugUIPresenter { ui_presenter, @@ -90,29 +97,35 @@ impl DebugUIPresenter where D: Device { let framebuffer_size = self.ui_presenter.framebuffer_size(); let bottom = framebuffer_size.y() - PADDING; let window_rect = RectI::new( - vec2i(framebuffer_size.x() - PADDING - INFO_WINDOW_WIDTH, - bottom - INFO_WINDOW_HEIGHT), + vec2i( + framebuffer_size.x() - PADDING - INFO_WINDOW_WIDTH, + bottom - INFO_WINDOW_HEIGHT, + ), vec2i(INFO_WINDOW_WIDTH, INFO_WINDOW_HEIGHT), ); - self.ui_presenter.draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR); + self.ui_presenter + .draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR); let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT); let level = match self.renderer_level { RendererLevel::D3D9 => "D3D9", RendererLevel::D3D11 => "D3D11", }; - self.ui_presenter.draw_text(device, - allocator, - &format!("{} ({} level)", self.backend_name, level), - origin + vec2i(0, LINE_HEIGHT * 0), - false); - self.ui_presenter.draw_text(device, - allocator, - &self.device_name, - origin + vec2i(0, LINE_HEIGHT * 1), - false); - + self.ui_presenter.draw_text( + device, + allocator, + &format!("{} ({} level)", self.backend_name, level), + origin + vec2i(0, LINE_HEIGHT * 0), + false, + ); + self.ui_presenter.draw_text( + device, + allocator, + &self.device_name, + origin + vec2i(0, LINE_HEIGHT * 1), + false, + ); } fn performance_window_size(&self) -> Vector2I { @@ -130,16 +143,20 @@ impl DebugUIPresenter where D: Device { 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 - - PADDING - - INFO_WINDOW_HEIGHT - - performance_window_height - - PADDING - - STATS_WINDOW_HEIGHT), - vec2i(STATS_WINDOW_WIDTH, STATS_WINDOW_HEIGHT)); + vec2i( + framebuffer_size.x() - PADDING - STATS_WINDOW_WIDTH, + bottom + - PADDING + - INFO_WINDOW_HEIGHT + - performance_window_height + - PADDING + - STATS_WINDOW_HEIGHT, + ), + vec2i(STATS_WINDOW_WIDTH, STATS_WINDOW_HEIGHT), + ); - self.ui_presenter.draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR); + self.ui_presenter + .draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR); let mean_cpu_sample = self.cpu_samples.mean(); let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT); @@ -179,11 +196,15 @@ impl DebugUIPresenter where D: Device { 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_size.x(), - bottom - INFO_WINDOW_HEIGHT - PADDING - performance_window_size.y()), - performance_window_size); + vec2i( + framebuffer_size.x() - PADDING - performance_window_size.x(), + bottom - INFO_WINDOW_HEIGHT - PADDING - performance_window_size.y(), + ), + performance_window_size, + ); - self.ui_presenter.draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR); + self.ui_presenter + .draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR); let mean_cpu_sample = self.cpu_samples.mean(); let mean_gpu_sample = self.gpu_samples.mean(); @@ -201,8 +222,10 @@ impl DebugUIPresenter where D: Device { self.ui_presenter.draw_text( device, allocator, - &format!("VRAM Alloc.: {:.1} MB", - mean_cpu_sample.gpu_bytes_allocated as f64 / (1024.0 * 1024.0)), + &format!( + "VRAM Alloc.: {:.1} MB", + mean_cpu_sample.gpu_bytes_allocated as f64 / (1024.0 * 1024.0) + ), origin + vec2i(0, current_y), false, ); @@ -210,8 +233,10 @@ impl DebugUIPresenter where D: Device { self.ui_presenter.draw_text( device, allocator, - &format!("VRAM Commit: {:.1} MB", - mean_cpu_sample.gpu_bytes_committed as f64 / (1024.0 * 1024.0)), + &format!( + "VRAM Commit: {:.1} MB", + mean_cpu_sample.gpu_bytes_committed as f64 / (1024.0 * 1024.0) + ), origin + vec2i(0, current_y), false, ); @@ -220,7 +245,10 @@ impl DebugUIPresenter where D: Device { self.ui_presenter.draw_text( device, allocator, - &format!("CPU: {:.3} ms", duration_to_ms(mean_cpu_sample.cpu_build_time)), + &format!( + "CPU: {:.3} ms", + duration_to_ms(mean_cpu_sample.cpu_build_time) + ), origin + vec2i(0, current_y), false, ); @@ -231,7 +259,10 @@ impl DebugUIPresenter where D: Device { self.ui_presenter.draw_text( device, allocator, - &format!("GPU Dice: {:.3} ms", duration_to_ms(mean_gpu_sample.dice_time)), + &format!( + "GPU Dice: {:.3} ms", + duration_to_ms(mean_gpu_sample.dice_time) + ), origin + vec2i(0, current_y), false, ); @@ -239,7 +270,10 @@ impl DebugUIPresenter where D: Device { self.ui_presenter.draw_text( device, allocator, - &format!("GPU Bin: {:.3} ms", duration_to_ms(mean_gpu_sample.bin_time)), + &format!( + "GPU Bin: {:.3} ms", + duration_to_ms(mean_gpu_sample.bin_time) + ), origin + vec2i(0, current_y), false, ); @@ -250,7 +284,10 @@ impl DebugUIPresenter where D: Device { self.ui_presenter.draw_text( device, allocator, - &format!("GPU Fill: {:.3} ms", duration_to_ms(mean_gpu_sample.fill_time)), + &format!( + "GPU Fill: {:.3} ms", + duration_to_ms(mean_gpu_sample.fill_time) + ), origin + vec2i(0, current_y), false, ); @@ -258,7 +295,10 @@ impl DebugUIPresenter where D: Device { self.ui_presenter.draw_text( device, allocator, - &format!("GPU Comp.: {:.3} ms", duration_to_ms(mean_gpu_sample.composite_time)), + &format!( + "GPU Comp.: {:.3} ms", + duration_to_ms(mean_gpu_sample.composite_time) + ), origin + vec2i(0, current_y), false, ); @@ -266,7 +306,10 @@ impl DebugUIPresenter where D: Device { self.ui_presenter.draw_text( device, allocator, - &format!("GPU Other: {:.3} ms", duration_to_ms(mean_gpu_sample.other_time)), + &format!( + "GPU Other: {:.3} ms", + duration_to_ms(mean_gpu_sample.other_time) + ), origin + vec2i(0, current_y), false, ); @@ -274,18 +317,18 @@ impl DebugUIPresenter where D: Device { let mut wallclock_time = match self.renderer_level { RendererLevel::D3D11 => { - duration_to_ms(mean_cpu_sample.cpu_build_time) + - duration_to_ms(mean_gpu_sample.fill_time) - } - RendererLevel::D3D9 => { - f64::max(duration_to_ms(mean_cpu_sample.cpu_build_time), - duration_to_ms(mean_gpu_sample.fill_time)) + duration_to_ms(mean_cpu_sample.cpu_build_time) + + duration_to_ms(mean_gpu_sample.fill_time) } + RendererLevel::D3D9 => f64::max( + duration_to_ms(mean_cpu_sample.cpu_build_time), + duration_to_ms(mean_gpu_sample.fill_time), + ), }; - wallclock_time += duration_to_ms(mean_gpu_sample.composite_time) + - duration_to_ms(mean_gpu_sample.dice_time) + - duration_to_ms(mean_gpu_sample.bin_time) + - duration_to_ms(mean_gpu_sample.other_time); + wallclock_time += duration_to_ms(mean_gpu_sample.composite_time) + + duration_to_ms(mean_gpu_sample.dice_time) + + duration_to_ms(mean_gpu_sample.bin_time) + + duration_to_ms(mean_gpu_sample.other_time); self.ui_presenter.draw_text( device, allocator, @@ -294,7 +337,6 @@ impl DebugUIPresenter where D: Device { false, ); } - } struct SampleBuffer diff --git a/renderer/src/gpu/mod.rs b/renderer/src/gpu/mod.rs index 322bb99b..033ed412 100644 --- a/renderer/src/gpu/mod.rs +++ b/renderer/src/gpu/mod.rs @@ -10,8 +10,8 @@ //! The GPU renderer for Pathfinder 3. -pub mod d3d9; pub mod d3d11; +pub mod d3d9; pub mod debug; pub mod options; pub mod perf; diff --git a/renderer/src/gpu/options.rs b/renderer/src/gpu/options.rs index 50f751d3..e54a2cc1 100644 --- a/renderer/src/gpu/options.rs +++ b/renderer/src/gpu/options.rs @@ -22,7 +22,10 @@ pub struct RendererMode { } /// Options that influence rendering that can be changed at runtime. -pub struct RendererOptions where D: Device { +pub struct RendererOptions +where + D: Device, +{ /// Where the rendering should go: either to the default framebuffer (i.e. screen) or to a /// custom framebuffer. pub dest: DestFramebuffer, @@ -48,12 +51,20 @@ pub enum RendererLevel { impl RendererMode { /// Creates a new `RendererMode` with a suitable API level for the given GPU device. #[inline] - pub fn default_for_device(device: &D) -> RendererMode where D: Device { - RendererMode { level: RendererLevel::default_for_device(device) } + pub fn default_for_device(device: &D) -> RendererMode + where + D: Device, + { + RendererMode { + level: RendererLevel::default_for_device(device), + } } } -impl Default for RendererOptions where D: Device { +impl Default for RendererOptions +where + D: Device, +{ #[inline] fn default() -> RendererOptions { RendererOptions { @@ -66,7 +77,10 @@ impl Default for RendererOptions where D: Device { impl RendererLevel { /// Returns a suitable renderer level for the given device. - pub fn default_for_device(device: &D) -> RendererLevel where D: Device { + pub fn default_for_device(device: &D) -> RendererLevel + where + D: Device, + { match device.feature_level() { FeatureLevel::D3D10 => RendererLevel::D3D9, FeatureLevel::D3D11 => RendererLevel::D3D11, @@ -76,7 +90,10 @@ impl RendererLevel { /// Where the rendered content should go. #[derive(Clone)] -pub enum DestFramebuffer where D: Device { +pub enum DestFramebuffer +where + D: Device, +{ /// The rendered content should go to the default framebuffer (e.g. the window in OpenGL). Default { /// The rectangle within the window to draw in, in device pixels. @@ -88,22 +105,34 @@ pub enum DestFramebuffer where D: Device { Other(D::Framebuffer), } -impl Default for DestFramebuffer where D: Device { +impl Default for DestFramebuffer +where + D: Device, +{ #[inline] fn default() -> DestFramebuffer { - DestFramebuffer::Default { viewport: RectI::default(), window_size: Vector2I::default() } + DestFramebuffer::Default { + viewport: RectI::default(), + window_size: Vector2I::default(), + } } } -impl DestFramebuffer where D: Device { +impl DestFramebuffer +where + D: Device, +{ /// Returns a `DestFramebuffer` object that renders to the entire contents of the default /// framebuffer. - /// + /// /// The `window_size` parameter specifies the size of the window in device pixels. #[inline] pub fn full_window(window_size: Vector2I) -> DestFramebuffer { let viewport = RectI::new(Vector2I::default(), window_size); - DestFramebuffer::Default { viewport, window_size } + DestFramebuffer::Default { + viewport, + window_size, + } } /// Returns the size of the destination buffer, in device pixels. diff --git a/renderer/src/gpu/perf.rs b/renderer/src/gpu/perf.rs index 81db829e..1b38d40a 100644 --- a/renderer/src/gpu/perf.rs +++ b/renderer/src/gpu/perf.rs @@ -22,7 +22,7 @@ pub struct RenderStats { /// The total number of path objects in the scene. pub path_count: usize, /// The number of fill operations it took to render the scene. - /// + /// /// A fill operation is a single edge in a 16x16 device pixel tile. pub fill_count: usize, /// The total number of 16x16 device pixel tile masks generated. @@ -35,7 +35,7 @@ pub struct RenderStats { /// The number of GPU API draw calls it took to render the scene. pub drawcall_count: u32, /// The number of bytes of VRAM Pathfinder has allocated. - /// + /// /// This may be higher than `gpu_bytes_committed` because Pathfinder caches some data for /// faster reuse. pub gpu_bytes_allocated: u64, @@ -75,11 +75,17 @@ impl Div for RenderStats { } } -pub(crate) struct TimerQueryCache where D: Device { +pub(crate) struct TimerQueryCache +where + D: Device, +{ free_queries: Vec, } -pub(crate) struct PendingTimer where D: Device { +pub(crate) struct PendingTimer +where + D: Device, +{ pub(crate) dice_times: Vec>, pub(crate) bin_times: Vec>, pub(crate) fill_times: Vec>, @@ -87,7 +93,10 @@ pub(crate) struct PendingTimer where D: Device { pub(crate) other_times: Vec>, } -pub(crate) enum TimerFuture where D: Device { +pub(crate) enum TimerFuture +where + D: Device, +{ Pending(D::TimerQuery), Resolved(Duration), } @@ -101,21 +110,31 @@ pub(crate) enum TimeCategory { Other, } -impl TimerQueryCache where D: Device { +impl TimerQueryCache +where + D: Device, +{ pub(crate) fn new() -> TimerQueryCache { - TimerQueryCache { free_queries: vec![] } + TimerQueryCache { + free_queries: vec![], + } } pub(crate) fn alloc(&mut self, device: &D) -> D::TimerQuery { - self.free_queries.pop().unwrap_or_else(|| device.create_timer_query()) + self.free_queries + .pop() + .unwrap_or_else(|| device.create_timer_query()) } pub(crate) fn free(&mut self, old_query: D::TimerQuery) { self.free_queries.push(old_query); } - pub(crate) fn start_timing_draw_call(&mut self, device: &D, options: &RendererOptions) - -> Option { + pub(crate) fn start_timing_draw_call( + &mut self, + device: &D, + options: &RendererOptions, + ) -> Option { if !options.show_debug_ui { return None; } @@ -126,7 +145,10 @@ impl TimerQueryCache where D: Device { } } -impl PendingTimer where D: Device { +impl PendingTimer +where + D: Device, +{ pub(crate) fn new() -> PendingTimer { PendingTimer { dice_times: vec![], @@ -139,10 +161,14 @@ impl PendingTimer where D: Device { pub(crate) fn poll(&mut self, device: &D) -> Vec { let mut old_queries = vec![]; - for future in self.dice_times.iter_mut().chain(self.bin_times.iter_mut()) - .chain(self.fill_times.iter_mut()) - .chain(self.composite_times.iter_mut()) - .chain(self.other_times.iter_mut()) { + for future in self + .dice_times + .iter_mut() + .chain(self.bin_times.iter_mut()) + .chain(self.fill_times.iter_mut()) + .chain(self.composite_times.iter_mut()) + .chain(self.other_times.iter_mut()) + { if let Some(old_query) = future.poll(device) { old_queries.push(old_query) } @@ -157,20 +183,28 @@ impl PendingTimer where D: Device { let composite_time = total_time_of_timer_futures(&self.composite_times); let other_time = total_time_of_timer_futures(&self.other_times); match (dice_time, bin_time, fill_time, composite_time, other_time) { - (Some(dice_time), - Some(bin_time), - Some(fill_time), - Some(composite_time), - Some(other_time)) => { - Some(RenderTime { dice_time, bin_time, fill_time, composite_time, other_time }) - } + ( + Some(dice_time), + Some(bin_time), + Some(fill_time), + Some(composite_time), + Some(other_time), + ) => Some(RenderTime { + dice_time, + bin_time, + fill_time, + composite_time, + other_time, + }), _ => None, } } - pub(crate) fn push_query(&mut self, - time_category: TimeCategory, - timer_query: Option) { + pub(crate) fn push_query( + &mut self, + time_category: TimeCategory, + timer_query: Option, + ) { let timer_future = match timer_query { None => return, Some(timer_query) => TimerFuture::new(timer_query), @@ -185,7 +219,10 @@ impl PendingTimer where D: Device { } } -impl TimerFuture where D: Device { +impl TimerFuture +where + D: Device, +{ pub(crate) fn new(query: D::TimerQuery) -> TimerFuture { TimerFuture::Pending(query) } @@ -197,17 +234,18 @@ impl TimerFuture where D: Device { }; match duration { None => None, - Some(duration) => { - match mem::replace(self, TimerFuture::Resolved(duration)) { - TimerFuture::Resolved(_) => unreachable!(), - TimerFuture::Pending(old_query) => Some(old_query), - } - } + Some(duration) => match mem::replace(self, TimerFuture::Resolved(duration)) { + TimerFuture::Resolved(_) => unreachable!(), + TimerFuture::Pending(old_query) => Some(old_query), + }, } } } -fn total_time_of_timer_futures(futures: &[TimerFuture]) -> Option where D: Device { +fn total_time_of_timer_futures(futures: &[TimerFuture]) -> Option +where + D: Device, +{ let mut total = Duration::default(); for future in futures { match *future { @@ -222,11 +260,11 @@ fn total_time_of_timer_futures(futures: &[TimerFuture]) -> Option where D: Device { +pub struct Renderer +where + D: Device, +{ // Basic data pub(crate) core: RendererCore, level_impl: RendererLevelImpl, @@ -92,12 +99,18 @@ pub struct Renderer where D: Device { last_rendering_time: Option, } -enum RendererLevelImpl where D: Device { +enum RendererLevelImpl +where + D: Device, +{ D3D9(RendererD3D9), D3D11(RendererD3D11), } -pub(crate) struct RendererCore where D: Device { +pub(crate) struct RendererCore +where + D: Device, +{ // Basic data pub(crate) device: D, pub(crate) allocator: GPUMemoryAllocator, @@ -135,7 +148,10 @@ pub(crate) struct RendererCore where D: Device { } // TODO(pcwalton): Remove this. -struct Frame where D: Device { +struct Frame +where + D: Device, +{ blit_vertex_array: BlitVertexArray, clear_vertex_array: ClearVertexArray, stencil_vertex_array: StencilVertexArray, @@ -147,88 +163,111 @@ pub(crate) struct MaskStorage { pub(crate) allocated_page_count: u32, } -impl Renderer where D: Device { +impl Renderer +where + D: Device, +{ /// Creates a new renderer ready to render Pathfinder content. - /// + /// /// Arguments: - /// + /// /// * `device`: The GPU device to render with. This effectively specifies the system GPU API /// Pathfinder will use (OpenGL, Metal, etc.) - /// + /// /// * `resources`: Where Pathfinder should find shaders, lookup tables, and other data. /// This is typically either an `EmbeddedResourceLoader` to use resources included in the /// Pathfinder library or (less commonly) a `FilesystemResourceLoader` to use resources /// stored in a directory on disk. - /// + /// /// * `mode`: Renderer options that can't be changed after the renderer is created. Most /// notably, this specifies the API level (D3D9 or D3D11). - /// + /// /// * `options`: Renderer options that can be changed after the renderer is created. Most /// importantly, this specifies where the output should go (to a window or off-screen). - pub fn new(device: D, - resources: &dyn ResourceLoader, - mode: RendererMode, - options: RendererOptions) - -> Renderer { + pub fn new( + device: D, + resources: &dyn ResourceLoader, + mode: RendererMode, + options: RendererOptions, + ) -> Renderer { let mut allocator = GPUMemoryAllocator::new(); device.begin_commands(); - let quad_vertex_positions_buffer_id = - allocator.allocate_general_buffer::(&device, - QUAD_VERTEX_POSITIONS.len() as u64, - BufferTag("QuadVertexPositions")); - device.upload_to_buffer(allocator.get_general_buffer(quad_vertex_positions_buffer_id), - 0, - &QUAD_VERTEX_POSITIONS, - BufferTarget::Vertex); - let quad_vertex_indices_buffer_id = - allocator.allocate_index_buffer::(&device, - QUAD_VERTEX_INDICES.len() as u64, - BufferTag("QuadVertexIndices")); - device.upload_to_buffer(allocator.get_index_buffer(quad_vertex_indices_buffer_id), - 0, - &QUAD_VERTEX_INDICES, - BufferTarget::Index); + let quad_vertex_positions_buffer_id = allocator.allocate_general_buffer::( + &device, + QUAD_VERTEX_POSITIONS.len() as u64, + BufferTag("QuadVertexPositions"), + ); + device.upload_to_buffer( + allocator.get_general_buffer(quad_vertex_positions_buffer_id), + 0, + &QUAD_VERTEX_POSITIONS, + BufferTarget::Vertex, + ); + let quad_vertex_indices_buffer_id = allocator.allocate_index_buffer::( + &device, + QUAD_VERTEX_INDICES.len() as u64, + BufferTag("QuadVertexIndices"), + ); + device.upload_to_buffer( + allocator.get_index_buffer(quad_vertex_indices_buffer_id), + 0, + &QUAD_VERTEX_INDICES, + BufferTarget::Index, + ); - let area_lut_texture_id = allocator.allocate_texture(&device, - Vector2I::splat(256), - TextureFormat::RGBA8, - TextureTag("AreaLUT")); - let gamma_lut_texture_id = allocator.allocate_texture(&device, - vec2i(256, 8), - TextureFormat::R8, - TextureTag("GammaLUT")); - device.upload_png_to_texture(resources, - "area-lut", - allocator.get_texture(area_lut_texture_id), - TextureFormat::RGBA8); - device.upload_png_to_texture(resources, - "gamma-lut", - allocator.get_texture(gamma_lut_texture_id), - TextureFormat::R8); + let area_lut_texture_id = allocator.allocate_texture( + &device, + Vector2I::splat(256), + TextureFormat::RGBA8, + TextureTag("AreaLUT"), + ); + let gamma_lut_texture_id = allocator.allocate_texture( + &device, + vec2i(256, 8), + TextureFormat::R8, + TextureTag("GammaLUT"), + ); + device.upload_png_to_texture( + resources, + "area-lut", + allocator.get_texture(area_lut_texture_id), + TextureFormat::RGBA8, + ); + device.upload_png_to_texture( + resources, + "gamma-lut", + allocator.get_texture(gamma_lut_texture_id), + TextureFormat::R8, + ); let window_size = options.dest.window_size(&device); - let intermediate_dest_framebuffer_id = - allocator.allocate_framebuffer(&device, - window_size, - TextureFormat::RGBA8, - FramebufferTag("IntermediateDest")); + let intermediate_dest_framebuffer_id = allocator.allocate_framebuffer( + &device, + window_size, + TextureFormat::RGBA8, + FramebufferTag("IntermediateDest"), + ); - let texture_metadata_texture_size = vec2i(TEXTURE_METADATA_TEXTURE_WIDTH, - TEXTURE_METADATA_TEXTURE_HEIGHT); - let texture_metadata_texture_id = - allocator.allocate_texture(&device, - texture_metadata_texture_size, - TextureFormat::RGBA16F, - TextureTag("TextureMetadata")); + let texture_metadata_texture_size = vec2i( + TEXTURE_METADATA_TEXTURE_WIDTH, + TEXTURE_METADATA_TEXTURE_HEIGHT, + ); + let texture_metadata_texture_id = allocator.allocate_texture( + &device, + texture_metadata_texture_size, + TextureFormat::RGBA16F, + TextureTag("TextureMetadata"), + ); let core_programs = ProgramsCore::new(&device, resources); - let core_vertex_arrays = - VertexArraysCore::new(&device, - &core_programs, - allocator.get_general_buffer(quad_vertex_positions_buffer_id), - allocator.get_index_buffer(quad_vertex_indices_buffer_id)); + let core_vertex_arrays = VertexArraysCore::new( + &device, + &core_programs, + allocator.get_general_buffer(quad_vertex_positions_buffer_id), + allocator.get_index_buffer(quad_vertex_indices_buffer_id), + ); let mut core = RendererCore { device, @@ -261,9 +300,7 @@ impl Renderer where D: Device { }; let level_impl = match core.mode.level { - RendererLevel::D3D9 => { - RendererLevelImpl::D3D9(RendererD3D9::new(&mut core, resources)) - } + RendererLevel::D3D9 => RendererLevelImpl::D3D9(RendererD3D9::new(&mut core, resources)), RendererLevel::D3D11 => { RendererLevelImpl::D3D11(RendererD3D11::new(&mut core, resources)) } @@ -275,19 +312,26 @@ impl Renderer where D: Device { let reprojection_program = ReprojectionProgram::new(&core.device, resources); let debug_ui_presenter = if core.options.show_debug_ui { - Some(DebugUIPresenter::new(&core.device, resources, window_size, core.mode.level)) + Some(DebugUIPresenter::new( + &core.device, + resources, + window_size, + core.mode.level, + )) } else { None }; - let frame = Frame::new(&core.device, - &mut core.allocator, - &blit_program, - &clear_program, - &reprojection_program, - &stencil_program, - quad_vertex_positions_buffer_id, - quad_vertex_indices_buffer_id); + let frame = Frame::new( + &core.device, + &mut core.allocator, + &blit_program, + &clear_program, + &reprojection_program, + &stencil_program, + quad_vertex_positions_buffer_id, + quad_vertex_indices_buffer_id, + ); core.device.end_commands(); @@ -317,7 +361,7 @@ impl Renderer where D: Device { } /// Performs work necessary to begin rendering a scene. - /// + /// /// This must be called before `render_command()`. pub fn begin_scene(&mut self) { self.core.framebuffer_flags = FramebufferFlags::empty(); @@ -330,52 +374,67 @@ impl Renderer where D: Device { } /// Issues a rendering command to the renderer. - /// + /// /// These commands are generated from methods like `Scene::build()`. - /// + /// /// `begin_scene()` must have been called first. pub fn render_command(&mut self, command: &RenderCommand) { debug!("render command: {:?}", command); match *command { - RenderCommand::Start { bounding_quad, path_count, needs_readable_framebuffer } => { + 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_pattern_texture_page(page_id, descriptor) - } - RenderCommand::UploadTexelData { ref texels, location } => { - self.upload_texel_data(texels, location) - } + RenderCommand::AllocateTexturePage { + page_id, + ref descriptor, + } => self.allocate_pattern_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::AddFillsD3D9(ref fills) => { - self.level_impl.require_d3d9().add_fills(&mut self.core, fills) - } + RenderCommand::AddFillsD3D9(ref fills) => self + .level_impl + .require_d3d9() + .add_fills(&mut self.core, fills), RenderCommand::FlushFillsD3D9 => { - self.level_impl.require_d3d9().draw_buffered_fills(&mut self.core); - } - RenderCommand::UploadSceneD3D11 { ref draw_segments, ref clip_segments } => { self.level_impl - .require_d3d11() - .upload_scene(&mut self.core, draw_segments, clip_segments) + .require_d3d9() + .draw_buffered_fills(&mut self.core); } + RenderCommand::UploadSceneD3D11 { + ref draw_segments, + ref clip_segments, + } => self.level_impl.require_d3d11().upload_scene( + &mut self.core, + draw_segments, + clip_segments, + ), RenderCommand::PushRenderTarget(render_target_id) => { self.push_render_target(render_target_id) } RenderCommand::PopRenderTarget => self.pop_render_target(), - RenderCommand::PrepareClipTilesD3D11(ref batch) => { - self.level_impl.require_d3d11().prepare_tiles(&mut self.core, batch) - } - RenderCommand::DrawTilesD3D9(ref batch) => { - self.level_impl.require_d3d9().upload_and_draw_tiles(&mut self.core, batch) - } - RenderCommand::DrawTilesD3D11(ref batch) => { - self.level_impl.require_d3d11().prepare_and_draw_tiles(&mut self.core, batch) - } + RenderCommand::PrepareClipTilesD3D11(ref batch) => self + .level_impl + .require_d3d11() + .prepare_tiles(&mut self.core, batch), + RenderCommand::DrawTilesD3D9(ref batch) => self + .level_impl + .require_d3d9() + .upload_and_draw_tiles(&mut self.core, batch), + RenderCommand::DrawTilesD3D11(ref batch) => self + .level_impl + .require_d3d11() + .prepare_and_draw_tiles(&mut self.core, batch), RenderCommand::Finish { cpu_build_time } => { self.core.stats.cpu_build_time = cpu_build_time; } @@ -383,10 +442,10 @@ impl Renderer where D: Device { } /// Finishes rendering a scene. - /// + /// /// `begin_scene()` and all `render_command()` calls must have been issued before calling this /// method. - /// + /// /// Note that, after calling this method, you might need to flush the output to the screen via /// `swap_buffers()`, `present()`, or a similar method that your windowing library offers. pub fn end_scene(&mut self) { @@ -418,10 +477,12 @@ impl Renderer where D: Device { self.core.device.end_commands(); } - fn start_rendering(&mut self, - bounding_quad: BoundingQuad, - path_count: usize, - needs_readable_framebuffer: bool) { + fn start_rendering( + &mut self, + bounding_quad: BoundingQuad, + path_count: usize, + needs_readable_framebuffer: bool, + ) { match (&self.core.options.dest, self.core.mode.level) { (&DestFramebuffer::Other(_), _) => { self.core @@ -434,10 +495,10 @@ impl Renderer where D: Device { .insert(RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED); } _ => { - self.core - .renderer_flags - .set(RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED, - needs_readable_framebuffer); + self.core.renderer_flags.set( + RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED, + needs_readable_framebuffer, + ); } } @@ -494,7 +555,7 @@ impl Renderer where D: Device { } /// Returns a reference to the GPU device. - /// + /// /// This can be useful to issue GPU commands manually via the low-level `pathfinder_gpu` /// abstraction. (Of course, you can also use your platform API such as OpenGL directly /// alongside Pathfinder.) @@ -504,7 +565,7 @@ impl Renderer where D: Device { } /// Returns a mutable reference to the GPU device. - /// + /// /// This can be useful to issue GPU commands manually via the low-level `pathfinder_gpu` /// abstraction. (Of course, you can also use your platform API such as OpenGL directly /// alongside Pathfinder.) @@ -526,10 +587,10 @@ impl Renderer where D: Device { } /// Returns a mutable reference to the current rendering options, allowing them to be changed. - /// + /// /// Among other things, you can use this function to change the destination of rendering /// output without having to recreate the renderer. - /// + /// /// After changing the destination framebuffer size, you must call /// `dest_framebuffer_size_changed()`. pub fn options_mut(&mut self) -> &mut RendererOptions { @@ -537,26 +598,31 @@ impl Renderer where D: Device { } /// Notifies Pathfinder that the size of the output framebuffer has changed. - /// + /// /// You must call this function after changing the `dest_framebuffer` member of /// `RendererOptions` to a target with a different size. #[inline] pub fn dest_framebuffer_size_changed(&mut self) { let new_framebuffer_size = self.core.main_viewport().size(); if let Some(ref mut debug_ui_presenter) = self.debug_ui_presenter { - debug_ui_presenter.ui_presenter.set_framebuffer_size(new_framebuffer_size); + debug_ui_presenter + .ui_presenter + .set_framebuffer_size(new_framebuffer_size); } } /// Returns a mutable reference to the debug UI. - /// + /// /// You can use this function to draw custom debug widgets on screen, as the demo does. #[inline] pub fn debug_ui_presenter_mut(&mut self) -> DebugUIPresenterInfo { DebugUIPresenterInfo { device: &mut self.core.device, allocator: &mut self.core.allocator, - debug_ui_presenter: self.debug_ui_presenter.as_mut().expect("Debug UI disabled!"), + debug_ui_presenter: self + .debug_ui_presenter + .as_mut() + .expect("Debug UI disabled!"), } } @@ -581,25 +647,31 @@ impl Renderer where D: Device { } /// Returns a GPU-side vertex buffer containing 2D vertices of a unit square. - /// + /// /// This can be handy for custom rendering. #[inline] pub fn quad_vertex_positions_buffer(&self) -> &D::Buffer { - self.core.allocator.get_general_buffer(self.core.quad_vertex_positions_buffer_id) + self.core + .allocator + .get_general_buffer(self.core.quad_vertex_positions_buffer_id) } /// Returns a GPU-side 32-bit unsigned index buffer of triangles necessary to render a quad /// with the buffer returned by `quad_vertex_positions_buffer()`. - /// + /// /// This can be handy for custom rendering. #[inline] pub fn quad_vertex_indices_buffer(&self) -> &D::Buffer { - self.core.allocator.get_index_buffer(self.core.quad_vertex_indices_buffer_id) + self.core + .allocator + .get_index_buffer(self.core.quad_vertex_indices_buffer_id) } - fn allocate_pattern_texture_page(&mut self, - page_id: TexturePageId, - descriptor: &TexturePageDescriptor) { + fn allocate_pattern_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.core.pattern_texture_pages.len() < page_index + 1 { @@ -608,17 +680,19 @@ impl Renderer where D: Device { // Clear out any existing texture. if let Some(old_texture_page) = self.core.pattern_texture_pages[page_index].take() { - self.core.allocator.free_framebuffer(old_texture_page.framebuffer_id); + self.core + .allocator + .free_framebuffer(old_texture_page.framebuffer_id); } // Allocate texture. let texture_size = descriptor.size; - let framebuffer_id = self.core - .allocator - .allocate_framebuffer(&self.core.device, - texture_size, - TextureFormat::RGBA8, - FramebufferTag("PatternPage")); + let framebuffer_id = self.core.allocator.allocate_framebuffer( + &self.core.device, + texture_size, + TextureFormat::RGBA8, + FramebufferTag("PatternPage"), + ); self.core.pattern_texture_pages[page_index] = Some(PatternTexturePage { framebuffer_id, must_preserve_contents: false, @@ -626,42 +700,50 @@ impl Renderer where D: Device { } fn upload_texel_data(&mut self, texels: &[ColorU], location: TextureLocation) { - let texture_page = self.core - .pattern_texture_pages[location.page.0 as usize] - .as_mut() - .expect("Texture page not allocated yet!"); + let texture_page = self.core.pattern_texture_pages[location.page.0 as usize] + .as_mut() + .expect("Texture page not allocated yet!"); let framebuffer_id = texture_page.framebuffer_id; let framebuffer = self.core.allocator.get_framebuffer(framebuffer_id); let texture = self.core.device.framebuffer_texture(framebuffer); let texels = color::color_slice_to_u8_slice(texels); - self.core.device.upload_to_texture(texture, location.rect, TextureDataRef::U8(texels)); + self.core + .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) { + fn declare_render_target( + &mut self, + render_target_id: RenderTargetId, + location: TextureLocation, + ) { while self.core.render_targets.len() < render_target_id.render_target as usize + 1 { self.core.render_targets.push(RenderTargetInfo { - location: TextureLocation { page: TexturePageId(!0), rect: RectI::default() }, + location: TextureLocation { + page: TexturePageId(!0), + rect: RectI::default(), + }, }); } - let render_target = - &mut self.core.render_targets[render_target_id.render_target as usize]; + let render_target = &mut self.core.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; + (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(); - let filter_params = self.compute_filter_params(&entry.filter, - entry.blend_mode, - entry.color_0_combine_mode); + let filter_params = self.compute_filter_params( + &entry.filter, + entry.blend_mode, + entry.color_0_combine_mode, + ); texels.extend_from_slice(&[ // 0 f16::from_f32(entry.color_0_transform.m11()), @@ -724,13 +806,17 @@ impl Renderer where D: Device { 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.core.device.upload_to_texture(texture, rect, TextureDataRef::F16(&texels)); + self.core + .device + .upload_to_texture(texture, rect, TextureDataRef::F16(&texels)); } fn draw_stencil(&mut self, quad_positions: &[Vector4F]) { - self.core.device.allocate_buffer(&self.frame.stencil_vertex_array.vertex_buffer, - BufferData::Memory(quad_positions), - BufferTarget::Vertex); + self.core.device.allocate_buffer( + &self.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.) @@ -738,70 +824,95 @@ impl Renderer where D: Device { for index in 1..(quad_positions.len() as u32 - 1) { indices.extend_from_slice(&[0, index as u32, index + 1]); } - self.core.device.allocate_buffer(&self.frame.stencil_vertex_array.index_buffer, - BufferData::Memory(&indices), - BufferTarget::Index); + self.core.device.allocate_buffer( + &self.frame.stencil_vertex_array.index_buffer, + BufferData::Memory(&indices), + BufferTarget::Index, + ); - self.core.device.draw_elements(indices.len() as u32, &RenderState { - target: &self.core.draw_render_target(), - program: &self.stencil_program.program, - vertex_array: &self.frame.stencil_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[], - images: &[], - storage_buffers: &[], - uniforms: &[], - viewport: self.core.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() + self.core.device.draw_elements( + indices.len() as u32, + &RenderState { + target: &self.core.draw_render_target(), + program: &self.stencil_program.program, + vertex_array: &self.frame.stencil_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[], + images: &[], + storage_buffers: &[], + uniforms: &[], + viewport: self.core.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() + }, }, - }); + ); self.core.stats.drawcall_count += 1; } - /// Draws a texture that was originally drawn with `old_transform` with `new_transform` by /// transforming in screen space. #[deprecated] - pub fn reproject_texture(&mut self, - texture: &D::Texture, - old_transform: &Transform4F, - new_transform: &Transform4F) { + pub fn reproject_texture( + &mut self, + texture: &D::Texture, + old_transform: &Transform4F, + new_transform: &Transform4F, + ) { let clear_color = self.core.clear_color_for_draw_operation(); - self.core.device.draw_elements(6, &RenderState { - target: &self.core.draw_render_target(), - program: &self.reprojection_program.program, - vertex_array: &self.frame.reprojection_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[(&self.reprojection_program.texture, texture)], - images: &[], - storage_buffers: &[], - 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)), - ], - viewport: self.core.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.core.device.draw_elements( + 6, + &RenderState { + target: &self.core.draw_render_target(), + program: &self.reprojection_program.program, + vertex_array: &self.frame.reprojection_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[(&self.reprojection_program.texture, texture)], + images: &[], + storage_buffers: &[], + 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), + ), + ], + viewport: self.core.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.core.stats.drawcall_count += 1; @@ -813,7 +924,10 @@ impl Renderer where D: Device { } fn pop_render_target(&mut self) { - self.core.render_target_stack.pop().expect("Render target stack underflow!"); + self.core + .render_target_stack + .pop() + .expect("Render target stack underflow!"); } fn clear_dest_framebuffer_if_necessary(&mut self) { @@ -822,84 +936,117 @@ impl Renderer where D: Device { Some(background_color) => background_color, }; - if self.core.framebuffer_flags.contains(FramebufferFlags::DEST_FRAMEBUFFER_IS_DIRTY) { + if self + .core + .framebuffer_flags + .contains(FramebufferFlags::DEST_FRAMEBUFFER_IS_DIRTY) + { return; } let main_viewport = self.core.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.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.core.device.draw_elements(6, &RenderState { - target: &RenderTarget::Default, - program: &self.clear_program.program, - vertex_array: &self.frame.clear_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[], - images: &[], - storage_buffers: &[], - uniforms: &uniforms[..], - viewport: main_viewport, - options: RenderOptions::default(), - }); + self.core.device.draw_elements( + 6, + &RenderState { + target: &RenderTarget::Default, + program: &self.clear_program.program, + vertex_array: &self.frame.clear_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[], + images: &[], + storage_buffers: &[], + uniforms: &uniforms[..], + viewport: main_viewport, + options: RenderOptions::default(), + }, + ); self.core.stats.drawcall_count += 1; } fn blit_intermediate_dest_framebuffer_if_necessary(&mut self) { - if !self.core - .renderer_flags - .contains(RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED) { + if !self + .core + .renderer_flags + .contains(RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED) + { return; } let main_viewport = self.core.main_viewport(); if self.core.intermediate_dest_framebuffer_size != main_viewport.size() { - self.core.allocator.free_framebuffer(self.core.intermediate_dest_framebuffer_id); - self.core.intermediate_dest_framebuffer_id = - self.core.allocator.allocate_framebuffer(&self.core.device, - main_viewport.size(), - TextureFormat::RGBA8, - FramebufferTag("IntermediateDest")); + self.core + .allocator + .free_framebuffer(self.core.intermediate_dest_framebuffer_id); + self.core.intermediate_dest_framebuffer_id = self.core.allocator.allocate_framebuffer( + &self.core.device, + main_viewport.size(), + TextureFormat::RGBA8, + FramebufferTag("IntermediateDest"), + ); self.core.intermediate_dest_framebuffer_size = main_viewport.size(); } - let intermediate_dest_framebuffer = - self.core.allocator.get_framebuffer(self.core.intermediate_dest_framebuffer_id); + let intermediate_dest_framebuffer = self + .core + .allocator + .get_framebuffer(self.core.intermediate_dest_framebuffer_id); - let textures = [ - (&self.blit_program.src_texture, - self.core.device.framebuffer_texture(intermediate_dest_framebuffer)) - ]; + let textures = [( + &self.blit_program.src_texture, + self.core + .device + .framebuffer_texture(intermediate_dest_framebuffer), + )]; - self.core.device.draw_elements(6, &RenderState { - target: &RenderTarget::Default, - program: &self.blit_program.program, - vertex_array: &self.frame.blit_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &textures[..], - images: &[], - storage_buffers: &[], - uniforms: &[ - (&self.blit_program.framebuffer_size_uniform, - UniformData::Vec2(main_viewport.size().to_f32().0)), - (&self.blit_program.dest_rect_uniform, - UniformData::Vec4(RectF::new(Vector2F::zero(), main_viewport.size().to_f32()).0)), - ], - viewport: main_viewport, - options: RenderOptions { - clear_ops: ClearOps { - color: Some(ColorF::new(0.0, 0.0, 0.0, 1.0)), - ..ClearOps::default() + self.core.device.draw_elements( + 6, + &RenderState { + target: &RenderTarget::Default, + program: &self.blit_program.program, + vertex_array: &self.frame.blit_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &textures[..], + images: &[], + storage_buffers: &[], + uniforms: &[ + ( + &self.blit_program.framebuffer_size_uniform, + UniformData::Vec2(main_viewport.size().to_f32().0), + ), + ( + &self.blit_program.dest_rect_uniform, + UniformData::Vec4( + RectF::new(Vector2F::zero(), main_viewport.size().to_f32()).0, + ), + ), + ], + viewport: main_viewport, + options: RenderOptions { + clear_ops: ClearOps { + color: Some(ColorF::new(0.0, 0.0, 0.0, 1.0)), + ..ClearOps::default() + }, + ..RenderOptions::default() }, - ..RenderOptions::default() }, - }); + ); self.core.stats.drawcall_count += 1; } @@ -917,27 +1064,30 @@ impl Renderer where D: Device { self.core.draw_render_target() } - fn compute_filter_params(&self, - filter: &Filter, - blend_mode: BlendMode, - color_0_combine_mode: ColorCombineMode) - -> FilterParams { + fn compute_filter_params( + &self, + filter: &Filter, + blend_mode: BlendMode, + color_0_combine_mode: ColorCombineMode, + ) -> FilterParams { let mut ctrl = 0; ctrl |= blend_mode.to_composite_ctrl() << COMBINER_CTRL_COMPOSITE_SHIFT; ctrl |= color_0_combine_mode.to_composite_ctrl() << COMBINER_CTRL_COLOR_COMBINE_SHIFT; match *filter { - Filter::RadialGradient { line, radii, uv_origin } => { - FilterParams { - p0: line.from().0.concat_xy_xy(line.vector().0), - p1: radii.concat_xy_xy(uv_origin.0), - p2: F32x4::default(), - p3: F32x4::default(), - p4: F32x4::default(), - ctrl: ctrl | (COMBINER_CTRL_FILTER_RADIAL_GRADIENT << - COMBINER_CTRL_COLOR_FILTER_SHIFT) - } - } + Filter::RadialGradient { + line, + radii, + uv_origin, + } => FilterParams { + p0: line.from().0.concat_xy_xy(line.vector().0), + p1: radii.concat_xy_xy(uv_origin.0), + p2: F32x4::default(), + p3: F32x4::default(), + p4: F32x4::default(), + ctrl: ctrl + | (COMBINER_CTRL_FILTER_RADIAL_GRADIENT << COMBINER_CTRL_COLOR_FILTER_SHIFT), + }, Filter::PatternFilter(PatternFilter::Blur { sigma, direction }) => { let sigma_inv = 1.0 / sigma; let gauss_coeff_x = SQRT_2_PI_INV * sigma_inv; @@ -960,7 +1110,7 @@ impl Renderer where D: Device { ctrl: ctrl | (COMBINER_CTRL_FILTER_BLUR << COMBINER_CTRL_COLOR_FILTER_SHIFT), } } - Filter::PatternFilter(PatternFilter::Text { + Filter::PatternFilter(PatternFilter::Text { fg_color, bg_color, defringing_kernel, @@ -984,25 +1134,31 @@ impl Renderer where D: Device { Filter::PatternFilter(PatternFilter::ColorMatrix(matrix)) => { let [p0, p1, p2, p3, p4] = matrix.0; FilterParams { - p0, p1, p2, p3, p4, - ctrl: ctrl | (COMBINER_CTRL_FILTER_COLOR_MATRIX << COMBINER_CTRL_COLOR_FILTER_SHIFT), - } - } - Filter::None => { - FilterParams { - p0: F32x4::default(), - p1: F32x4::default(), - p2: F32x4::default(), - p3: F32x4::default(), - p4: F32x4::default(), - ctrl, + p0, + p1, + p2, + p3, + p4, + ctrl: ctrl + | (COMBINER_CTRL_FILTER_COLOR_MATRIX << COMBINER_CTRL_COLOR_FILTER_SHIFT), } } + Filter::None => FilterParams { + p0: F32x4::default(), + p1: F32x4::default(), + p2: F32x4::default(), + p3: F32x4::default(), + p4: F32x4::default(), + ctrl, + }, } } } -impl RendererCore where D: Device { +impl RendererCore +where + D: Device, +{ pub(crate) fn mask_texture_format(&self) -> TextureFormat { match self.mode.level { RendererLevel::D3D9 => TextureFormat::RGBA16F, @@ -1018,14 +1174,17 @@ impl RendererCore where D: Device { } } - let new_size = vec2i(MASK_FRAMEBUFFER_WIDTH, - MASK_FRAMEBUFFER_HEIGHT * alpha_tile_pages_needed as i32); + let new_size = vec2i( + MASK_FRAMEBUFFER_WIDTH, + MASK_FRAMEBUFFER_HEIGHT * alpha_tile_pages_needed as i32, + ); let format = self.mask_texture_format(); - let mask_framebuffer_id = - self.allocator.allocate_framebuffer(&self.device, - new_size, - format, - FramebufferTag("TileAlphaMask")); + let mask_framebuffer_id = self.allocator.allocate_framebuffer( + &self.device, + new_size, + format, + FramebufferTag("TileAlphaMask"), + ); let mask_framebuffer = self.allocator.get_framebuffer(mask_framebuffer_id); let old_mask_storage = self.mask_storage.take(); self.mask_storage = Some(MaskStorage { @@ -1042,68 +1201,92 @@ impl RendererCore where D: Device { let old_mask_texture = self.device.framebuffer_texture(old_mask_framebuffer); let old_size = self.device.texture_size(old_mask_texture); - let timer_query = self.timer_query_cache.start_timing_draw_call(&self.device, - &self.options); + let timer_query = self + .timer_query_cache + .start_timing_draw_call(&self.device, &self.options); - self.device.draw_elements(6, &RenderState { - target: &RenderTarget::Framebuffer(mask_framebuffer), - program: &self.programs.blit_program.program, - vertex_array: &self.vertex_arrays.blit_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[(&self.programs.blit_program.src_texture, old_mask_texture)], - images: &[], - storage_buffers: &[], - uniforms: &[ - (&self.programs.blit_program.framebuffer_size_uniform, - UniformData::Vec2(new_size.to_f32().0)), - (&self.programs.blit_program.dest_rect_uniform, - UniformData::Vec4(RectF::new(Vector2F::zero(), old_size.to_f32()).0)), - ], - viewport: RectI::new(Vector2I::default(), new_size), - options: RenderOptions { - clear_ops: ClearOps { - color: Some(ColorF::new(0.0, 0.0, 0.0, 0.0)), - ..ClearOps::default() + self.device.draw_elements( + 6, + &RenderState { + target: &RenderTarget::Framebuffer(mask_framebuffer), + program: &self.programs.blit_program.program, + vertex_array: &self.vertex_arrays.blit_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[(&self.programs.blit_program.src_texture, old_mask_texture)], + images: &[], + storage_buffers: &[], + uniforms: &[ + ( + &self.programs.blit_program.framebuffer_size_uniform, + UniformData::Vec2(new_size.to_f32().0), + ), + ( + &self.programs.blit_program.dest_rect_uniform, + UniformData::Vec4(RectF::new(Vector2F::zero(), old_size.to_f32()).0), + ), + ], + viewport: RectI::new(Vector2I::default(), new_size), + options: RenderOptions { + clear_ops: ClearOps { + color: Some(ColorF::new(0.0, 0.0, 0.0, 0.0)), + ..ClearOps::default() + }, + ..RenderOptions::default() }, - ..RenderOptions::default() }, - }); + ); self.stats.drawcall_count += 1; self.finish_timing_draw_call(&timer_query); - self.current_timer.as_mut().unwrap().push_query(TimeCategory::Other, timer_query); + self.current_timer + .as_mut() + .unwrap() + .push_query(TimeCategory::Other, timer_query); } pub(crate) fn set_uniforms_for_drawing_tiles<'a>( - &'a self, - tile_program: &'a TileProgramCommon, - textures: &mut Vec>, - uniforms: &mut Vec>, - color_texture_0: Option) { + &'a self, + tile_program: &'a TileProgramCommon, + textures: &mut Vec>, + uniforms: &mut Vec>, + color_texture_0: Option, + ) { let draw_viewport = self.draw_viewport(); let gamma_lut_texture = self.allocator.get_texture(self.gamma_lut_texture_id); - self.allocator.get_texture(self.texture_metadata_texture_id); + self.allocator.get_texture(self.texture_metadata_texture_id); textures.push((&tile_program.gamma_lut_texture, gamma_lut_texture)); - let texture_metadata_texture = - self.allocator.get_texture(self.texture_metadata_texture_id); - textures.push((&tile_program.texture_metadata_texture, texture_metadata_texture)); + let texture_metadata_texture = self.allocator.get_texture(self.texture_metadata_texture_id); + textures.push(( + &tile_program.texture_metadata_texture, + texture_metadata_texture, + )); - uniforms.push((&tile_program.tile_size_uniform, - UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32)))); - uniforms.push((&tile_program.framebuffer_size_uniform, - UniformData::Vec2(draw_viewport.size().to_f32().0))); - uniforms.push((&tile_program.texture_metadata_size_uniform, - UniformData::IVec2(I32x2::new(TEXTURE_METADATA_TEXTURE_WIDTH, - TEXTURE_METADATA_TEXTURE_HEIGHT)))); + uniforms.push(( + &tile_program.tile_size_uniform, + UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32)), + )); + uniforms.push(( + &tile_program.framebuffer_size_uniform, + UniformData::Vec2(draw_viewport.size().to_f32().0), + )); + uniforms.push(( + &tile_program.texture_metadata_size_uniform, + UniformData::IVec2(I32x2::new( + TEXTURE_METADATA_TEXTURE_WIDTH, + TEXTURE_METADATA_TEXTURE_HEIGHT, + )), + )); if let Some(ref mask_storage) = self.mask_storage { let mask_framebuffer_id = mask_storage.framebuffer_id; let mask_framebuffer = self.allocator.get_framebuffer(mask_framebuffer_id); let mask_texture = self.device.framebuffer_texture(mask_framebuffer); - uniforms.push((&tile_program.mask_texture_size_0_uniform, - UniformData::Vec2(self.device.texture_size(mask_texture).to_f32().0))); + uniforms.push(( + &tile_program.mask_texture_size_0_uniform, + UniformData::Vec2(self.device.texture_size(mask_texture).to_f32().0), + )); textures.push((&tile_program.mask_texture_0, mask_texture)); } @@ -1111,17 +1294,21 @@ impl RendererCore where D: Device { 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); + self.device + .set_texture_sampling_mode(color_texture_page, color_texture.sampling_flags); textures.push((&tile_program.color_texture_0, color_texture_page)); - uniforms.push((&tile_program.color_texture_size_0_uniform, - UniformData::Vec2(color_texture_size.0))); + uniforms.push(( + &tile_program.color_texture_size_0_uniform, + UniformData::Vec2(color_texture_size.0), + )); } None => { // Attach any old texture, just to satisfy Metal. textures.push((&tile_program.color_texture_0, texture_metadata_texture)); - uniforms.push((&tile_program.color_texture_size_0_uniform, - UniformData::Vec2(F32x2::default()))); + uniforms.push(( + &tile_program.color_texture_size_0_uniform, + UniformData::Vec2(F32x2::default()), + )); } } } @@ -1129,14 +1316,15 @@ impl RendererCore where D: Device { // Pattern textures fn texture_page(&self, id: TexturePageId) -> &D::Texture { - self.device.framebuffer_texture(&self.texture_page_framebuffer(id)) + self.device + .framebuffer_texture(&self.texture_page_framebuffer(id)) } fn texture_page_framebuffer(&self, id: TexturePageId) -> &D::Framebuffer { let framebuffer_id = self.pattern_texture_pages[id.0 as usize] - .as_ref() - .expect("Texture page not allocated!") - .framebuffer_id; + .as_ref() + .expect("Texture page not allocated!") + .framebuffer_id; self.allocator.get_framebuffer(framebuffer_id) } @@ -1149,9 +1337,9 @@ impl RendererCore where D: Device { .expect("Draw target texture page not allocated!") .must_preserve_contents } - None => { - self.framebuffer_flags.contains(FramebufferFlags::DEST_FRAMEBUFFER_IS_DIRTY) - } + None => self + .framebuffer_flags + .contains(FramebufferFlags::DEST_FRAMEBUFFER_IS_DIRTY), }; if must_preserve_contents { @@ -1166,8 +1354,8 @@ impl RendererCore where D: Device { // Sizing pub(crate) fn tile_size(&self) -> Vector2I { - let temp = self.draw_viewport().size() + - vec2i(TILE_WIDTH as i32 - 1, TILE_HEIGHT as i32 - 1); + let temp = + self.draw_viewport().size() + vec2i(TILE_WIDTH as i32 - 1, TILE_HEIGHT as i32 - 1); vec2i(temp.x() / TILE_WIDTH as i32, temp.y() / TILE_HEIGHT as i32) } @@ -1203,10 +1391,13 @@ impl RendererCore where D: Device { RenderTarget::Framebuffer(framebuffer) } None => { - if self.renderer_flags - .contains(RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED) { - let intermediate_dest_framebuffer = - self.allocator.get_framebuffer(self.intermediate_dest_framebuffer_id); + if self + .renderer_flags + .contains(RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED) + { + let intermediate_dest_framebuffer = self + .allocator + .get_framebuffer(self.intermediate_dest_framebuffer_id); RenderTarget::Framebuffer(intermediate_dest_framebuffer) } else { match self.options.dest { @@ -1230,7 +1421,8 @@ impl RendererCore where D: Device { .must_preserve_contents = true; } None => { - self.framebuffer_flags.insert(FramebufferFlags::DEST_FRAMEBUFFER_IS_DIRTY); + self.framebuffer_flags + .insert(FramebufferFlags::DEST_FRAMEBUFFER_IS_DIRTY); } } } @@ -1246,34 +1438,43 @@ impl RendererCore where D: Device { } } -impl Frame where D: Device { +impl Frame +where + D: Device, +{ // FIXME(pcwalton): This signature shouldn't be so big. Make a struct. - fn new(device: &D, - allocator: &mut GPUMemoryAllocator, - blit_program: &BlitProgram, - clear_program: &ClearProgram, - reprojection_program: &ReprojectionProgram, - stencil_program: &StencilProgram, - quad_vertex_positions_buffer_id: GeneralBufferID, - quad_vertex_indices_buffer_id: IndexBufferID) - -> Frame { + fn new( + device: &D, + allocator: &mut GPUMemoryAllocator, + blit_program: &BlitProgram, + clear_program: &ClearProgram, + reprojection_program: &ReprojectionProgram, + stencil_program: &StencilProgram, + quad_vertex_positions_buffer_id: GeneralBufferID, + quad_vertex_indices_buffer_id: IndexBufferID, + ) -> Frame { let quad_vertex_positions_buffer = allocator.get_general_buffer(quad_vertex_positions_buffer_id); - let quad_vertex_indices_buffer = - allocator.get_index_buffer(quad_vertex_indices_buffer_id); + let quad_vertex_indices_buffer = allocator.get_index_buffer(quad_vertex_indices_buffer_id); - 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 reprojection_vertex_array = ReprojectionVertexArray::new(device, - &reprojection_program, - &quad_vertex_positions_buffer, - &quad_vertex_indices_buffer); + 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 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); Frame { @@ -1285,7 +1486,10 @@ impl Frame where D: Device { } } -impl RendererLevelImpl where D: Device { +impl RendererLevelImpl +where + D: Device, +{ #[inline] fn require_d3d9(&mut self) -> &mut RendererD3D9 { match *self { @@ -1354,9 +1558,12 @@ pub(crate) struct PatternTexturePage { } /// A mutable reference to the debug UI presenter. -/// +/// /// You can use this structure to draw custom debug widgets on screen, as the demo does. -pub struct DebugUIPresenterInfo<'a, D> where D: Device { +pub struct DebugUIPresenterInfo<'a, D> +where + D: Device, +{ /// The GPU device. pub device: &'a mut D, /// The GPU memory allocator. diff --git a/renderer/src/gpu/shaders.rs b/renderer/src/gpu/shaders.rs index d56cf5d2..4017ef38 100644 --- a/renderer/src/gpu/shaders.rs +++ b/renderer/src/gpu/shaders.rs @@ -15,105 +15,173 @@ use pathfinder_resources::ResourceLoader; // TODO(pcwalton): Replace with `mem::size_of` calls? pub(crate) const TILE_INSTANCE_SIZE: usize = 16; -pub(crate) struct BlitVertexArray where D: Device { +pub(crate) struct BlitVertexArray +where + D: Device, +{ pub(crate) vertex_array: D::VertexArray, } -impl BlitVertexArray where D: Device { - pub(crate) fn new(device: &D, - blit_program: &BlitProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> BlitVertexArray { +impl BlitVertexArray +where + D: Device, +{ + pub(crate) 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_attr = device.get_vertex_attr(&blit_program.program, "Position").unwrap(); + let position_attr = device + .get_vertex_attr(&blit_program.program, "Position") + .unwrap(); - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + device.bind_buffer( + &vertex_array, + quad_vertex_positions_buffer, + BufferTarget::Vertex, + ); + device.configure_vertex_attr( + &vertex_array, + &position_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }, + ); + device.bind_buffer( + &vertex_array, + quad_vertex_indices_buffer, + BufferTarget::Index, + ); BlitVertexArray { vertex_array } } } -pub(crate) struct VertexArraysCore where D: Device { +pub(crate) struct VertexArraysCore +where + D: Device, +{ pub(crate) blit_vertex_array: BlitVertexArray, } -impl VertexArraysCore where D: Device { - pub(crate) fn new(device: &D, - programs: &ProgramsCore, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> VertexArraysCore { +impl VertexArraysCore +where + D: Device, +{ + pub(crate) fn new( + device: &D, + programs: &ProgramsCore, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer, + ) -> VertexArraysCore { VertexArraysCore { - blit_vertex_array: BlitVertexArray::new(device, - &programs.blit_program, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer), + blit_vertex_array: BlitVertexArray::new( + device, + &programs.blit_program, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer, + ), } } } -pub(crate) struct ClearVertexArray where D: Device { +pub(crate) struct ClearVertexArray +where + D: Device, +{ pub(crate) vertex_array: D::VertexArray, } -impl ClearVertexArray where D: Device { - pub(crate) fn new(device: &D, - clear_program: &ClearProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> ClearVertexArray { +impl ClearVertexArray +where + D: Device, +{ + pub(crate) 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_attr = device.get_vertex_attr(&clear_program.program, "Position").unwrap(); + let position_attr = device + .get_vertex_attr(&clear_program.program, "Position") + .unwrap(); - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + device.bind_buffer( + &vertex_array, + quad_vertex_positions_buffer, + BufferTarget::Vertex, + ); + device.configure_vertex_attr( + &vertex_array, + &position_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }, + ); + device.bind_buffer( + &vertex_array, + quad_vertex_indices_buffer, + BufferTarget::Index, + ); ClearVertexArray { vertex_array } } } -pub(crate) struct BlitProgram where D: Device { +pub(crate) struct BlitProgram +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) dest_rect_uniform: D::Uniform, pub(crate) framebuffer_size_uniform: D::Uniform, pub(crate) src_texture: D::TextureParameter, } -impl BlitProgram where D: Device { +impl BlitProgram +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> BlitProgram { let program = device.create_raster_program(resources, "blit"); let dest_rect_uniform = device.get_uniform(&program, "DestRect"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let src_texture = device.get_texture_parameter(&program, "Src"); - BlitProgram { program, dest_rect_uniform, framebuffer_size_uniform, src_texture } + BlitProgram { + program, + dest_rect_uniform, + framebuffer_size_uniform, + src_texture, + } } } -pub(crate) struct ProgramsCore where D: Device { +pub(crate) struct ProgramsCore +where + D: Device, +{ pub(crate) blit_program: BlitProgram, } -impl ProgramsCore where D: Device { +impl ProgramsCore +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> ProgramsCore { ProgramsCore { blit_program: BlitProgram::new(device, resources), @@ -121,24 +189,38 @@ impl ProgramsCore where D: Device { } } -pub(crate) struct ClearProgram where D: Device { +pub(crate) struct ClearProgram +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) rect_uniform: D::Uniform, pub(crate) framebuffer_size_uniform: D::Uniform, pub(crate) color_uniform: D::Uniform, } -impl ClearProgram where D: Device { +impl ClearProgram +where + D: Device, +{ pub(crate) 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 } + ClearProgram { + program, + rect_uniform, + framebuffer_size_uniform, + color_uniform, + } } } -pub(crate) struct TileProgramCommon where D: Device { +pub(crate) struct TileProgramCommon +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) tile_size_uniform: D::Uniform, pub(crate) texture_metadata_texture: D::TextureParameter, @@ -153,7 +235,10 @@ pub(crate) struct TileProgramCommon where D: Device { pub(crate) framebuffer_size_uniform: D::Uniform, } -impl TileProgramCommon where D: Device { +impl TileProgramCommon +where + D: Device, +{ pub(crate) fn new(device: &D, program: D::Program) -> TileProgramCommon { let tile_size_uniform = device.get_uniform(&program, "TileSize"); let texture_metadata_texture = device.get_texture_parameter(&program, "TextureMetadata"); @@ -184,89 +269,142 @@ impl TileProgramCommon where D: Device { } } -pub(crate) struct StencilProgram where D: Device { +pub(crate) struct StencilProgram +where + D: Device, +{ pub(crate) program: D::Program, } -impl StencilProgram where D: Device { +impl StencilProgram +where + D: Device, +{ pub(crate) fn new(device: &D, resources: &dyn ResourceLoader) -> StencilProgram { let program = device.create_raster_program(resources, "stencil"); StencilProgram { program } } } -pub(crate) struct StencilVertexArray where D: Device { +pub(crate) struct StencilVertexArray +where + D: Device, +{ pub(crate) vertex_array: D::VertexArray, pub(crate) vertex_buffer: D::Buffer, pub(crate) index_buffer: D::Buffer, } -impl StencilVertexArray where D: Device { +impl StencilVertexArray +where + D: Device, +{ pub(crate) 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(); + 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.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 } + StencilVertexArray { + vertex_array, + vertex_buffer, + index_buffer, + } } } -pub(crate) struct ReprojectionProgram where D: Device { +pub(crate) struct ReprojectionProgram +where + D: Device, +{ pub(crate) program: D::Program, pub(crate) old_transform_uniform: D::Uniform, pub(crate) new_transform_uniform: D::Uniform, pub(crate) texture: D::TextureParameter, } -impl ReprojectionProgram where D: Device { +impl ReprojectionProgram +where + D: Device, +{ pub(crate) 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 = device.get_texture_parameter(&program, "Texture"); - ReprojectionProgram { program, old_transform_uniform, new_transform_uniform, texture } + ReprojectionProgram { + program, + old_transform_uniform, + new_transform_uniform, + texture, + } } } -pub(crate) struct ReprojectionVertexArray where D: Device { +pub(crate) struct ReprojectionVertexArray +where + D: Device, +{ pub(crate) vertex_array: D::VertexArray, } -impl ReprojectionVertexArray where D: Device { - pub(crate) fn new(device: &D, - reprojection_program: &ReprojectionProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> ReprojectionVertexArray { +impl ReprojectionVertexArray +where + D: Device, +{ + pub(crate) 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_attr = device.get_vertex_attr(&reprojection_program.program, "Position") - .unwrap(); + let position_attr = device + .get_vertex_attr(&reprojection_program.program, "Position") + .unwrap(); - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + device.bind_buffer( + &vertex_array, + quad_vertex_positions_buffer, + BufferTarget::Vertex, + ); + device.configure_vertex_attr( + &vertex_array, + &position_attr, + &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }, + ); + device.bind_buffer( + &vertex_array, + quad_vertex_indices_buffer, + BufferTarget::Index, + ); ReprojectionVertexArray { vertex_array } } diff --git a/renderer/src/gpu_data.rs b/renderer/src/gpu_data.rs index f098dbe5..de0cb4e0 100644 --- a/renderer/src/gpu_data.rs +++ b/renderer/src/gpu_data.rs @@ -24,15 +24,15 @@ use pathfinder_geometry::transform2d::Transform2F; use pathfinder_geometry::vector::{Vector2F, 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::sync::Arc; use std::time::Duration; use std::u32; -pub const TILE_CTRL_MASK_WINDING: i32 = 0x1; +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 const TILE_CTRL_MASK_0_SHIFT: i32 = 0; pub enum RenderCommand { // Starts rendering a frame. @@ -51,15 +51,24 @@ pub enum RenderCommand { }, // Allocates a texture page. - AllocateTexturePage { page_id: TexturePageId, descriptor: TexturePageDescriptor }, + AllocateTexturePage { + page_id: TexturePageId, + descriptor: TexturePageDescriptor, + }, // Uploads data to a texture page. - UploadTexelData { texels: Arc>, location: TextureLocation }, + 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 }, + DeclareRenderTarget { + id: RenderTargetId, + location: TextureLocation, + }, // Upload texture metadata. UploadTextureMetadata(Vec), @@ -71,7 +80,7 @@ pub enum RenderCommand { FlushFillsD3D9, /// Upload a scene to GPU. - /// + /// /// This will only be sent if dicing and binning is done on GPU. UploadSceneD3D11 { draw_segments: SegmentsD3D11, @@ -95,7 +104,9 @@ pub enum RenderCommand { DrawTilesD3D11(DrawTileBatchD3D11), // Presents a rendered frame. - Finish { cpu_build_time: Duration }, + Finish { + cpu_build_time: Duration, + }, } #[derive(Clone, Copy, PartialEq, Debug, Default)] @@ -116,7 +127,7 @@ pub struct TextureLocation { #[derive(Clone, Debug)] pub struct TileBatchDataD3D11 { /// The ID of this batch. - /// + /// /// The renderer should not assume that these values are consecutive. pub batch_id: TileBatchId, /// The number of paths in this batch. @@ -147,7 +158,7 @@ pub struct PrepareTilesInfoD3D11 { pub backdrops: Vec, /// Mapping from path index to metadata needed to compute propagation on GPU. - /// + /// /// This contains indices into the `tiles` vector. pub propagate_metadata: Vec, @@ -184,7 +195,7 @@ pub struct ClippedPathInfo { pub clipped_path_count: u32, /// The maximum number of clipped tiles. - /// + /// /// This is used to allocate vertex buffers. pub max_clipped_tile_count: u32, @@ -193,7 +204,7 @@ pub struct ClippedPathInfo { } /// Together with the `TileBatchId`, uniquely identifies a path on the renderer side. -/// +/// /// Generally, `PathIndex(!0)` represents no path. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub struct PathBatchIndex(pub u32); @@ -438,8 +449,10 @@ impl PathBatchIndex { impl AlphaTileId { #[inline] - pub fn new(next_alpha_tile_index: &[AtomicUsize; ALPHA_TILE_LEVEL_COUNT], level: usize) - -> AlphaTileId { + 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) @@ -470,11 +483,22 @@ impl Debug for RenderCommand { fn fmt(&self, formatter: &mut Formatter) -> DebugResult { match *self { RenderCommand::Start { .. } => write!(formatter, "Start"), - RenderCommand::AllocateTexturePage { page_id, descriptor: _ } => { + RenderCommand::AllocateTexturePage { + page_id, + descriptor: _, + } => { write!(formatter, "AllocateTexturePage({})", page_id.0) } - RenderCommand::UploadTexelData { ref texels, location } => { - write!(formatter, "UploadTexelData(x{:?}, {:?})", texels.len(), location) + RenderCommand::UploadTexelData { + ref texels, + location, + } => { + write!( + formatter, + "UploadTexelData(x{:?}, {:?})", + texels.len(), + location + ) } RenderCommand::DeclareRenderTarget { id, location } => { write!(formatter, "DeclareRenderTarget({:?}, {:?})", id, location) @@ -486,23 +510,29 @@ impl Debug for RenderCommand { write!(formatter, "AddFillsD3D9(x{})", fills.len()) } RenderCommand::FlushFillsD3D9 => write!(formatter, "FlushFills"), - RenderCommand::UploadSceneD3D11 { ref draw_segments, ref clip_segments } => { - write!(formatter, - "UploadSceneD3D11(DP x{}, DI x{}, CP x{}, CI x{})", - draw_segments.points.len(), - draw_segments.indices.len(), - clip_segments.points.len(), - clip_segments.indices.len()) + RenderCommand::UploadSceneD3D11 { + ref draw_segments, + ref clip_segments, + } => { + write!( + formatter, + "UploadSceneD3D11(DP x{}, DI x{}, CP x{}, CI x{})", + draw_segments.points.len(), + draw_segments.indices.len(), + clip_segments.points.len(), + clip_segments.indices.len() + ) } RenderCommand::PrepareClipTilesD3D11(ref batch) => { let clipped_path_count = match batch.clipped_path_info { None => 0, Some(ref clipped_path_info) => clipped_path_info.clipped_path_count, }; - write!(formatter, - "PrepareClipTilesD3D11({:?}, C {})", - batch.batch_id, - clipped_path_count) + write!( + formatter, + "PrepareClipTilesD3D11({:?}, C {})", + batch.batch_id, clipped_path_count + ) } RenderCommand::PushRenderTarget(render_target_id) => { write!(formatter, "PushRenderTarget({:?})", render_target_id) @@ -512,13 +542,18 @@ impl Debug for RenderCommand { write!(formatter, "DrawTilesD3D9(x{:?})", batch.tiles.len()) } RenderCommand::DrawTilesD3D11(ref batch) => { - write!(formatter, - "DrawTilesD3D11({:?}, C0 {:?})", - batch.tile_batch_data.batch_id, - batch.color_texture) + write!( + formatter, + "DrawTilesD3D11({:?}, C0 {:?})", + batch.tile_batch_data.batch_id, batch.color_texture + ) } RenderCommand::Finish { cpu_build_time } => { - write!(formatter, "Finish({} ms)", cpu_build_time.as_secs_f64() * 1000.0) + write!( + formatter, + "Finish({} ms)", + cpu_build_time.as_secs_f64() * 1000.0 + ) } } } diff --git a/renderer/src/options.rs b/renderer/src/options.rs index e6283568..76577d64 100644 --- a/renderer/src/options.rs +++ b/renderer/src/options.rs @@ -21,7 +21,7 @@ use pathfinder_geometry::vector::{Vector2F, Vector4F}; use pathfinder_content::clip::PolygonClipper3D; /// A sink for the render commands that scenes build. -/// +/// /// In single-threaded operation, this object typically buffers commands into an array and then, /// once scene building is complete, commands are all sent to the output at once. In multithreaded /// operation, on the other hand, commands are sent to the renderer on the fly as they're built. @@ -129,9 +129,10 @@ impl RenderTransform { } let inverse_transform = perspective.transform.inverse(); - let clip_polygon = points.into_iter() - .map(|point| (inverse_transform * point).to_2d()) - .collect(); + let clip_polygon = points + .into_iter() + .map(|point| (inverse_transform * point).to_2d()) + .collect(); return PreparedRenderTransform::Perspective { perspective, clip_polygon, @@ -166,17 +167,13 @@ impl PreparedBuildOptions { pub(crate) fn to_prepare_mode(&self, renderer_level: RendererLevel) -> PrepareMode { match renderer_level { RendererLevel::D3D9 => PrepareMode::CPU, - RendererLevel::D3D11 => { - match self.transform { - PreparedRenderTransform::Perspective { .. } => PrepareMode::TransformCPUBinGPU, - PreparedRenderTransform::None => { - PrepareMode::GPU { transform: Transform2F::default() } - } - PreparedRenderTransform::Transform2D(transform) => { - PrepareMode::GPU { transform } - } - } - } + RendererLevel::D3D11 => match self.transform { + PreparedRenderTransform::Perspective { .. } => PrepareMode::TransformCPUBinGPU, + PreparedRenderTransform::None => PrepareMode::GPU { + transform: Transform2F::default(), + }, + PreparedRenderTransform::Transform2D(transform) => PrepareMode::GPU { transform }, + }, } } } diff --git a/renderer/src/paint.rs b/renderer/src/paint.rs index 238f0e64..7bfa1157 100644 --- a/renderer/src/paint.rs +++ b/renderer/src/paint.rs @@ -23,7 +23,7 @@ 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_geometry::vector::{vec2f, vec2i, Vector2F, Vector2I}; use pathfinder_gpu::TextureSamplingFlags; use pathfinder_simd::default::{F32x2, F32x4}; use std::f32; @@ -118,7 +118,10 @@ impl Paint { /// Creates a simple paint from a single base color. #[inline] pub fn from_color(color: ColorU) -> Paint { - Paint { base_color: color, overlay: None } + Paint { + base_color: color, + overlay: None, + } } /// Creates a paint from a gradient. @@ -167,12 +170,10 @@ impl Paint { 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(), - } - } + Some(ref overlay) => match overlay.contents { + PaintContents::Gradient(ref gradient) => gradient.is_opaque(), + PaintContents::Pattern(ref pattern) => pattern.is_opaque(), + }, } } @@ -186,12 +187,10 @@ impl Paint { match self.overlay { None => true, - Some(ref overlay) => { - match overlay.contents { - PaintContents::Gradient(ref gradient) => gradient.is_fully_transparent(), - PaintContents::Pattern(_) => false, - } - } + Some(ref overlay) => match overlay.contents { + PaintContents::Gradient(ref gradient) => gradient.is_fully_transparent(), + PaintContents::Pattern(_) => false, + }, } } @@ -251,12 +250,10 @@ impl Paint { pub fn pattern(&self) -> Option<&Pattern> { match self.overlay { None => None, - Some(ref overlay) => { - match overlay.contents { - PaintContents::Pattern(ref pattern) => Some(pattern), - _ => None, - } - } + Some(ref overlay) => match overlay.contents { + PaintContents::Pattern(ref pattern) => Some(pattern), + _ => None, + }, } } @@ -265,12 +262,10 @@ impl Paint { 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, - } - } + Some(ref mut overlay) => match overlay.contents { + PaintContents::Pattern(ref mut pattern) => Some(pattern), + _ => None, + }, } } @@ -279,12 +274,10 @@ impl Paint { pub fn gradient(&self) -> Option<&Gradient> { match self.overlay { None => None, - Some(ref overlay) => { - match overlay.contents { - PaintContents::Gradient(ref gradient) => Some(gradient), - _ => None, - } - } + Some(ref overlay) => match overlay.contents { + PaintContents::Gradient(ref gradient) => Some(gradient), + _ => None, + }, } } } @@ -392,13 +385,17 @@ impl Palette { pub(crate) fn push_render_target(&mut self, render_target: RenderTarget) -> RenderTargetId { let id = self.render_targets.len() as u32; self.render_targets.push(render_target); - RenderTargetId { scene: self.scene_id.0, render_target: id } + RenderTargetId { + scene: self.scene_id.0, + render_target: id, + } } - pub(crate) fn build_paint_info(&mut self, - texture_manager: &mut PaintTextureManager, - render_transform: Transform2F) - -> PaintInfo { + pub(crate) fn build_paint_info( + &mut self, + texture_manager: &mut PaintTextureManager, + render_transform: Transform2F, + ) -> PaintInfo { // Assign render target locations. let mut transient_paint_locations = vec![]; let render_target_metadata = @@ -410,9 +407,11 @@ impl Palette { gradient_tile_builder, image_texel_info, used_image_hashes, - } = self.assign_paint_locations(&render_target_metadata, - texture_manager, - &mut transient_paint_locations); + } = self.assign_paint_locations( + &render_target_metadata, + texture_manager, + &mut transient_paint_locations, + ); // Calculate texture transforms. self.calculate_texture_transforms(&mut paint_metadata, texture_manager, render_transform); @@ -425,36 +424,45 @@ impl Palette { self.allocate_textures(&mut render_commands, texture_manager); // Create render commands. - self.create_render_commands(&mut render_commands, - render_target_metadata, - gradient_tile_builder, - image_texel_info); + self.create_render_commands( + &mut render_commands, + render_target_metadata, + gradient_tile_builder, + image_texel_info, + ); // Free transient locations and unused images, now that they're no longer needed. self.free_transient_locations(texture_manager, transient_paint_locations); self.free_unused_images(texture_manager, used_image_hashes); - PaintInfo { render_commands, paint_metadata } + PaintInfo { + render_commands, + paint_metadata, + } } - fn assign_render_target_locations(&self, - texture_manager: &mut PaintTextureManager, - transient_paint_locations: &mut Vec) - -> Vec { + fn assign_render_target_locations( + &self, + texture_manager: &mut PaintTextureManager, + transient_paint_locations: &mut Vec, + ) -> Vec { let mut render_target_metadata = vec![]; for render_target in &self.render_targets { - let location = texture_manager.allocator.allocate_image(render_target.size()); + let location = texture_manager + .allocator + .allocate_image(render_target.size()); render_target_metadata.push(RenderTargetMetadata { location }); transient_paint_locations.push(location); } render_target_metadata } - fn assign_paint_locations(&self, - render_target_metadata: &[RenderTargetMetadata], - texture_manager: &mut PaintTextureManager, - transient_paint_locations: &mut Vec) - -> PaintLocationsInfo { + fn assign_paint_locations( + &self, + render_target_metadata: &[RenderTargetMetadata], + texture_manager: &mut PaintTextureManager, + transient_paint_locations: &mut Vec, + ) -> PaintLocationsInfo { let mut paint_metadata = vec![]; let mut gradient_tile_builder = GradientTileBuilder::new(); let mut image_texel_info = vec![]; @@ -476,10 +484,11 @@ impl Palette { // FIXME(pcwalton): The gradient size might not be big enough. Detect // this. - let location = - gradient_tile_builder.allocate(allocator, - transient_paint_locations, - gradient); + let location = gradient_tile_builder.allocate( + allocator, + transient_paint_locations, + gradient, + ); Some(PaintColorTextureMetadata { location, page_scale: allocator.page_scale(location.page), @@ -496,12 +505,17 @@ impl Palette { }) } PaintContents::Pattern(ref pattern) => { - let border = vec2i(if pattern.repeat_x() { 0 } else { 1 }, - if pattern.repeat_y() { 0 } else { 1 }); + let border = vec2i( + if pattern.repeat_x() { 0 } else { 1 }, + if pattern.repeat_y() { 0 } else { 1 }, + ); let location; match *pattern.source() { - PatternSource::RenderTarget { id: render_target_id, .. } => { + PatternSource::RenderTarget { + id: render_target_id, + .. + } => { let index = render_target_id.render_target as usize; location = render_target_metadata[index].location; } @@ -519,9 +533,11 @@ impl Palette { let allocation_mode = AllocationMode::OwnPage; location = allocator.allocate( image.size() + border * 2, - allocation_mode); - texture_manager.cached_images.insert(image_hash, - location); + allocation_mode, + ); + texture_manager + .cached_images + .insert(image_hash, location); } } image_texel_info.push(ImageTexelInfo { @@ -542,8 +558,10 @@ impl Palette { sampling_flags.insert(TextureSamplingFlags::REPEAT_V); } if !pattern.smoothing_enabled() { - sampling_flags.insert(TextureSamplingFlags::NEAREST_MIN | - TextureSamplingFlags::NEAREST_MAG); + sampling_flags.insert( + TextureSamplingFlags::NEAREST_MIN + | TextureSamplingFlags::NEAREST_MAG, + ); } let filter = match pattern.filter() { @@ -582,24 +600,28 @@ impl Palette { } } - fn calculate_texture_transforms(&self, - paint_metadata: &mut [PaintMetadata], - texture_manager: &mut PaintTextureManager, - render_transform: Transform2F) { + fn calculate_texture_transforms( + &self, + paint_metadata: &mut [PaintMetadata], + texture_manager: &mut PaintTextureManager, + render_transform: Transform2F, + ) { for (paint, metadata) in self.paints.iter().zip(paint_metadata.iter_mut()) { let color_texture_metadata = match metadata.color_texture_metadata { None => continue, Some(ref mut color_texture_metadata) => color_texture_metadata, }; - let texture_scale = texture_manager.allocator - .page_scale(color_texture_metadata.location.page); + let texture_scale = texture_manager + .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 { + 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), .. @@ -620,16 +642,16 @@ impl Palette { 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() + 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() + Transform2F::from_translation(texture_origin_uv) + * Transform2F::from_scale(texture_scale * vec2f(1.0, -1.0)) + * pattern.transform().inverse() } } } @@ -638,10 +660,13 @@ impl Palette { } } - fn create_texture_metadata(&self, paint_metadata: &[PaintMetadata]) - -> Vec { - paint_metadata.iter().map(|paint_metadata| { - TextureMetadataEntry { + fn create_texture_metadata( + &self, + paint_metadata: &[PaintMetadata], + ) -> Vec { + 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, @@ -654,31 +679,41 @@ impl Palette { base_color: paint_metadata.base_color, filter: paint_metadata.filter(), blend_mode: paint_metadata.blend_mode, - } - }).collect() + }) + .collect() } - fn allocate_textures(&self, - render_commands: &mut Vec, - texture_manager: &mut PaintTextureManager) { + fn allocate_textures( + &self, + render_commands: &mut Vec, + texture_manager: &mut PaintTextureManager, + ) { for page_id in texture_manager.allocator.page_ids() { let page_size = texture_manager.allocator.page_size(page_id); let descriptor = TexturePageDescriptor { size: page_size }; if texture_manager.allocator.page_is_new(page_id) { - render_commands.push(RenderCommand::AllocateTexturePage { page_id, descriptor }); + render_commands.push(RenderCommand::AllocateTexturePage { + page_id, + descriptor, + }); } } texture_manager.allocator.mark_all_pages_as_allocated(); } - fn create_render_commands(&self, - render_commands: &mut Vec, - render_target_metadata: Vec, - gradient_tile_builder: GradientTileBuilder, - image_texel_info: Vec) { + fn create_render_commands( + &self, + render_commands: &mut Vec, + render_target_metadata: Vec, + gradient_tile_builder: GradientTileBuilder, + image_texel_info: Vec, + ) { for (index, metadata) in render_target_metadata.iter().enumerate() { - let id = RenderTargetId { scene: self.scene_id.0, render_target: index as u32 }; + let id = RenderTargetId { + scene: self.scene_id.0, + render_target: index as u32, + }; render_commands.push(RenderCommand::DeclareRenderTarget { id, location: metadata.location, @@ -693,18 +728,22 @@ impl Palette { } } - fn free_transient_locations(&self, - texture_manager: &mut PaintTextureManager, - transient_paint_locations: Vec) { + fn free_transient_locations( + &self, + texture_manager: &mut PaintTextureManager, + transient_paint_locations: Vec, + ) { for location in transient_paint_locations { texture_manager.allocator.free(location); } } // Frees images that are cached but not used this frame. - fn free_unused_images(&self, - texture_manager: &mut PaintTextureManager, - used_image_hashes: HashSet) { + fn free_unused_images( + &self, + texture_manager: &mut PaintTextureManager, + used_image_hashes: HashSet, + ) { let cached_images = &mut texture_manager.cached_images; let allocator = &mut texture_manager.allocator; cached_images.retain(|image_hash, location| { @@ -719,9 +758,9 @@ impl Palette { 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() { + 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, @@ -736,31 +775,33 @@ impl Palette { 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), - } + 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 } + MergedPaletteInfo { + render_target_mapping, + paint_mapping, + } } } @@ -782,25 +823,27 @@ 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) + 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) + self.color_texture_metadata + .as_ref() + .map(PaintColorTextureMetadata::as_tile_batch_texture) } } @@ -825,13 +868,13 @@ impl GradientTileBuilder { GradientTileBuilder { tiles: vec![] } } - fn allocate(&mut self, - allocator: &mut TextureAllocator, - transient_paint_locations: &mut Vec, - gradient: &Gradient) - -> TextureLocation { - if self.tiles.is_empty() || - self.tiles.last().unwrap().next_index == GRADIENT_TILE_LENGTH { + fn allocate( + &mut self, + allocator: &mut TextureAllocator, + transient_paint_locations: &mut Vec, + 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; let page_location = allocator.allocate(size, AllocationMode::OwnPage); @@ -846,8 +889,10 @@ impl GradientTileBuilder { let 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)), + rect: RectI::new( + vec2i(0, data.next_index as i32), + vec2i(GRADIENT_TILE_LENGTH as i32, 1), + ), }; data.next_index += 1; diff --git a/renderer/src/scene.rs b/renderer/src/scene.rs index 351d777a..6d47adb2 100644 --- a/renderer/src/scene.rs +++ b/renderer/src/scene.rs @@ -24,7 +24,7 @@ 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 pathfinder_geometry::vector::{vec2f, Vector2I}; use pathfinder_gpu::Device; use std::mem; use std::ops::Range; @@ -90,7 +90,9 @@ impl Scene { let end_path_id = DrawPathId(draw_path_id.0 + 1); match self.display_list.last_mut() { Some(DisplayItem::DrawPaths(ref mut range)) => range.end = end_path_id, - _ => self.display_list.push(DisplayItem::DrawPaths(draw_path_id..end_path_id)), + _ => self + .display_list + .push(DisplayItem::DrawPaths(draw_path_id..end_path_id)), } self.epoch.next(); @@ -111,7 +113,8 @@ impl Scene { /// top of the stack. 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)); + self.display_list + .push(DisplayItem::PushRenderTarget(render_target_id)); self.epoch.next(); render_target_id } @@ -161,7 +164,8 @@ impl Scene { 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)); + self.display_list + .push(DisplayItem::PushRenderTarget(new_render_target_id)); } DisplayItem::PopRenderTarget => { self.display_list.push(DisplayItem::PopRenderTarget); @@ -180,11 +184,13 @@ impl Scene { } #[inline] - pub(crate) fn build_paint_info(&mut self, - texture_manager: &mut PaintTextureManager, - render_transform: Transform2F) - -> PaintInfo { - self.palette.build_paint_info(texture_manager, render_transform) + pub(crate) fn build_paint_info( + &mut self, + texture_manager: &mut PaintTextureManager, + render_transform: Transform2F, + ) -> PaintInfo { + self.palette + .build_paint_info(texture_manager, render_transform) } /// Defines a new paint, which specifies how paths are to be filled or stroked. Returns a paint @@ -227,10 +233,11 @@ impl Scene { } #[allow(deprecated)] - pub(crate) fn apply_render_options(&self, - original_outline: &Outline, - options: &PreparedBuildOptions) - -> Outline { + pub(crate) fn apply_render_options( + &self, + original_outline: &Outline, + options: &PreparedBuildOptions, + ) -> Outline { let mut outline; match options.transform { PreparedRenderTransform::Perspective { @@ -289,11 +296,14 @@ impl Scene { /// `SequentialExecutor` to prepare commands on a single thread or `RayonExecutor` to prepare /// commands in parallel across multiple threads. #[inline] - pub fn build<'a, 'b, E>(&mut self, - options: BuildOptions, - sink: &'b mut SceneSink<'a>, - executor: &E) - where E: Executor { + pub fn build<'a, 'b, E>( + &mut self, + options: BuildOptions, + sink: &'b mut SceneSink<'a>, + executor: &E, + ) where + E: Executor, + { let prepared_options = options.prepare(self.bounds); SceneBuilder::new(self, &prepared_options, sink).build(executor) } @@ -334,7 +344,10 @@ impl Scene { /// Returns the paint with the given ID. #[inline] pub fn get_paint(&self, paint_id: PaintId) -> &Paint { - self.palette.paints.get(paint_id.0 as usize).expect("No paint with that ID!") + self.palette + .paints + .get(paint_id.0 as usize) + .expect("No paint with that ID!") } /// Returns the globally-unique ID of the scene. @@ -349,12 +362,16 @@ impl Scene { } /// A convenience method to build a scene and accumulate commands into a vector. - pub fn build_into_vector(&mut self, - renderer: &mut Renderer, - build_options: BuildOptions, - executor: E) - -> Vec - where D: Device, E: Executor { + pub fn build_into_vector( + &mut self, + renderer: &mut Renderer, + build_options: BuildOptions, + executor: E, + ) -> Vec + where + D: Device, + E: Executor, + { let commands = Arc::new(Mutex::new(vec![])); let commands_for_listener = commands.clone(); let listener = RenderCommandListener::new(Box::new(move |command| { @@ -368,11 +385,15 @@ impl Scene { /// A convenience method to build a scene and send the resulting commands to the given /// renderer. - pub fn build_and_render(&mut self, - renderer: &mut Renderer, - build_options: BuildOptions, - executor: E) - where D: Device, E: Executor + Send { + pub fn build_and_render( + &mut self, + renderer: &mut Renderer, + build_options: BuildOptions, + executor: E, + ) where + D: Device, + E: Executor + Send, + { std::thread::scope(move |scope| { let (tx, rx) = flume::bounded(MAX_MESSAGES_IN_FLIGHT); @@ -380,9 +401,8 @@ impl Scene { // TODO: avoid this auxiliary thread scope.spawn(move || { - let listener = RenderCommandListener::new(Box::new(move |command| { - tx.send(command).unwrap() - })); + let listener = + RenderCommandListener::new(Box::new(move |command| tx.send(command).unwrap())); let mut sink = SceneSink::new(listener, level); self.build(build_options, &mut sink, &executor); }); @@ -430,9 +450,15 @@ impl SceneEpoch { #[inline] fn successor(&self) -> SceneEpoch { if self.lo == u64::MAX { - SceneEpoch { hi: self.hi + 1, lo: 0 } + SceneEpoch { + hi: self.hi + 1, + lo: 0, + } } else { - SceneEpoch { hi: self.hi, lo: self.lo + 1 } + SceneEpoch { + hi: self.hi, + lo: self.lo + 1, + } } } @@ -445,8 +471,10 @@ impl SceneEpoch { impl<'a> SceneSink<'a> { /// Creates a new scene sink from the given render command listener and level. #[inline] - pub fn new(listener: RenderCommandListener<'a>, renderer_level: RendererLevel) - -> SceneSink<'a> { + pub fn new( + listener: RenderCommandListener<'a>, + renderer_level: RendererLevel, + ) -> SceneSink<'a> { SceneSink { listener, renderer_level, @@ -607,7 +635,12 @@ impl ClipPath { /// has no name. #[inline] pub fn new(outline: Outline) -> ClipPath { - ClipPath { outline, clip_path: None, fill_rule: FillRule::Winding, name: String::new() } + ClipPath { + outline, + clip_path: None, + fill_rule: FillRule::Winding, + name: String::new(), + } } /// Returns the outline of this clip path, which defines its vector commands. diff --git a/renderer/src/tile_map.rs b/renderer/src/tile_map.rs index 3922b6b3..a844752e 100644 --- a/renderer/src/tile_map.rs +++ b/renderer/src/tile_map.rs @@ -9,18 +9,26 @@ // except according to those terms. use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::{Vector2I, vec2i}; +use pathfinder_geometry::vector::{vec2i, Vector2I}; #[derive(Clone, Debug)] -pub struct DenseTileMap where T: Clone + Copy { +pub struct DenseTileMap +where + T: Clone + Copy, +{ pub data: Vec, pub rect: RectI, } -impl DenseTileMap where T: Clone + Copy { +impl DenseTileMap +where + T: Clone + Copy, +{ #[inline] pub fn from_builder(mut build: F, rect: RectI) -> DenseTileMap - where F: FnMut(Vector2I) -> T { + where + F: FnMut(Vector2I) -> T, + { let mut data = Vec::with_capacity(rect.size().x() as usize * rect.size().y() as usize); for y in rect.min_y()..rect.max_y() { for x in rect.min_x()..rect.max_x() { @@ -32,7 +40,8 @@ impl DenseTileMap where T: Clone + Copy { #[inline] pub fn get(&self, coords: Vector2I) -> Option<&T> { - self.coords_to_index(coords).and_then(|index| self.data.get(index)) + self.coords_to_index(coords) + .and_then(|index| self.data.get(index)) } #[inline] diff --git a/renderer/src/tiler.rs b/renderer/src/tiler.rs index 2b4c541d..a4dede7d 100644 --- a/renderer/src/tiler.rs +++ b/renderer/src/tiler.rs @@ -16,14 +16,14 @@ use crate::gpu::options::RendererLevel; use crate::gpu_data::AlphaTileId; use crate::options::PrepareMode; use crate::scene::{ClipPathId, PathId}; -use crate::tiles::{TILE_HEIGHT, TILE_WIDTH, TilingPathInfo}; +use crate::tiles::{TilingPathInfo, TILE_HEIGHT, TILE_WIDTH}; use pathfinder_content::clip; use pathfinder_content::fill::FillRule; use pathfinder_content::outline::{ContourIterFlags, Outline}; use pathfinder_content::segment::Segment; use pathfinder_geometry::line_segment::LineSegment2F; use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2f, vec2i}; +use pathfinder_geometry::vector::{vec2f, vec2i, Vector2F, Vector2I}; use pathfinder_simd::default::{F32x2, U32x2}; use std::f32::NEG_INFINITY; @@ -37,32 +37,43 @@ pub(crate) struct Tiler<'a, 'b, 'c, 'd> { } impl<'a, 'b, 'c, 'd> Tiler<'a, 'b, 'c, 'd> { - pub(crate) fn new(scene_builder: &'a SceneBuilder<'b, 'a, 'c, 'd>, - path_id: PathId, - outline: &'a Outline, - fill_rule: FillRule, - view_box: RectF, - prepare_mode: &PrepareMode, - clip_path_id: Option, - built_clip_paths: &'a [BuiltPath], - path_info: TilingPathInfo) - -> Tiler<'a, 'b, 'c, 'd> { - let bounds = outline.bounds().intersection(view_box).unwrap_or(RectF::default()); + pub(crate) fn new( + scene_builder: &'a SceneBuilder<'b, 'a, 'c, 'd>, + path_id: PathId, + outline: &'a Outline, + fill_rule: FillRule, + view_box: RectF, + prepare_mode: &PrepareMode, + clip_path_id: Option, + built_clip_paths: &'a [BuiltPath], + path_info: TilingPathInfo, + ) -> Tiler<'a, 'b, 'c, 'd> { + let bounds = outline + .bounds() + .intersection(view_box) + .unwrap_or(RectF::default()); let clip_path = match clip_path_id { Some(clip_path_id) => Some(&built_clip_paths[clip_path_id.0 as usize]), _ => None, }; - let object_builder = ObjectBuilder::new(path_id, - bounds, - view_box, - fill_rule, - prepare_mode, - clip_path_id, - &path_info); + let object_builder = ObjectBuilder::new( + path_id, + bounds, + view_box, + fill_rule, + prepare_mode, + clip_path_id, + &path_info, + ); - Tiler { scene_builder, object_builder, outline, clip_path } + Tiler { + scene_builder, + object_builder, + outline, + clip_path, + } } pub(crate) fn generate_tiles(&mut self) { @@ -93,9 +104,11 @@ impl<'a, 'b, 'c, 'd> Tiler<'a, 'b, 'c, 'd> { fn prepare_tiles(&mut self) { // Don't do this here if the GPU will do it. let (backdrops, tiles, clips) = match self.object_builder.built_path.data { - BuiltPathData::CPU(ref mut tiled_data) => { - (&mut tiled_data.backdrops, &mut tiled_data.tiles, &mut tiled_data.clip_tiles) - } + BuiltPathData::CPU(ref mut tiled_data) => ( + &mut tiled_data.backdrops, + &mut tiled_data.tiles, + &mut tiled_data.clip_tiles, + ), BuiltPathData::TransformCPUBinGPU(_) | BuiltPathData::GPU => { panic!("We shouldn't be preparing tiles on CPU!") } @@ -118,30 +131,34 @@ impl<'a, 'b, 'c, 'd> Tiler<'a, 'b, 'c, 'd> { }; match clip_tiles.get(tile_coords) { Some(clip_tile) => { - if clip_tile.alpha_tile_id != AlphaTileId(!0) && - draw_alpha_tile_id != AlphaTileId(!0) { + if clip_tile.alpha_tile_id != AlphaTileId(!0) + && draw_alpha_tile_id != AlphaTileId(!0) + { // Hard case: We have an alpha tile and a clip tile with masks. Add a // job to combine the two masks. Because the mask combining step // applies the backdrops, zero out the backdrop in the draw tile itself // so that we don't double-count it. - let clip = clips.as_mut() - .expect("Where are the clips?") - .get_mut(tile_coords) - .unwrap(); + let clip = clips + .as_mut() + .expect("Where are the clips?") + .get_mut(tile_coords) + .unwrap(); clip.dest_tile_id = draw_tile.alpha_tile_id; clip.dest_backdrop = draw_tile_backdrop as i32; clip.src_tile_id = clip_tile.alpha_tile_id; clip.src_backdrop = clip_tile.backdrop as i32; draw_tile_backdrop = 0; - } else if clip_tile.alpha_tile_id != AlphaTileId(!0) && - draw_alpha_tile_id == AlphaTileId(!0) && - draw_tile_backdrop != 0 { + } else if clip_tile.alpha_tile_id != AlphaTileId(!0) + && draw_alpha_tile_id == AlphaTileId(!0) + && draw_tile_backdrop != 0 + { // This is a solid draw tile, but there's a clip applied. Replace it // with an alpha tile pointing directly to the clip mask. draw_alpha_tile_id = clip_tile.alpha_tile_id; draw_tile_backdrop = clip_tile.backdrop; - } else if clip_tile.alpha_tile_id == AlphaTileId(!0) && - clip_tile.backdrop == 0 { + } else if clip_tile.alpha_tile_id == AlphaTileId(!0) + && clip_tile.backdrop == 0 + { // This is a blank clip tile. Cull the draw tile entirely. draw_alpha_tile_id = AlphaTileId(!0); draw_tile_backdrop = 0; @@ -163,17 +180,20 @@ impl<'a, 'b, 'c, 'd> Tiler<'a, 'b, 'c, 'd> { } } -fn process_segment(segment: &Segment, - scene_builder: &SceneBuilder, - object_builder: &mut ObjectBuilder) { +fn process_segment( + segment: &Segment, + scene_builder: &SceneBuilder, + object_builder: &mut ObjectBuilder, +) { // TODO(pcwalton): Stop degree elevating. if segment.is_quadratic() { let cubic = segment.to_cubic(); return process_segment(&cubic, scene_builder, object_builder); } - if segment.is_line() || - (segment.is_cubic() && segment.as_cubic_segment().is_flat(FLATTENING_TOLERANCE)) { + if segment.is_line() + || (segment.is_cubic() && segment.as_cubic_segment().is_flat(FLATTENING_TOLERANCE)) + { return process_line_segment(segment.baseline, scene_builder, object_builder); } @@ -188,12 +208,16 @@ fn process_segment(segment: &Segment, // // The algorithm to step through tiles is Amanatides and Woo, "A Fast Voxel Traversal Algorithm for // Ray Tracing" 1987: http://www.cse.yorku.ca/~amana/research/grid.pdf -fn process_line_segment(line_segment: LineSegment2F, - scene_builder: &SceneBuilder, - object_builder: &mut ObjectBuilder) { +fn process_line_segment( + line_segment: LineSegment2F, + scene_builder: &SceneBuilder, + object_builder: &mut ObjectBuilder, +) { let view_box = scene_builder.scene.view_box(); - let clip_box = RectF::from_points(vec2f(view_box.min_x(), NEG_INFINITY), - view_box.lower_right()); + let clip_box = RectF::from_points( + vec2f(view_box.min_x(), NEG_INFINITY), + view_box.lower_right(), + ); let line_segment = match clip::clip_line_segment_to_rect(line_segment, clip_box) { None => return, Some(line_segment) => line_segment, @@ -202,8 +226,9 @@ fn process_line_segment(line_segment: LineSegment2F, let tile_size = vec2f(TILE_WIDTH as f32, TILE_HEIGHT as f32); let tile_size_recip = Vector2F::splat(1.0) / tile_size; - let tile_line_segment = - (line_segment.0 * tile_size_recip.0.concat_xy_xy(tile_size_recip.0)).floor().to_i32x4(); + let tile_line_segment = (line_segment.0 * tile_size_recip.0.concat_xy_xy(tile_size_recip.0)) + .floor() + .to_i32x4(); let from_tile_coords = Vector2I(tile_line_segment.xy()); let to_tile_coords = Vector2I(tile_line_segment.zw()); @@ -216,8 +241,9 @@ fn process_line_segment(line_segment: LineSegment2F, // Compute `first_tile_crossing = (from_tile_coords + vec2i(vector.x >= 0 ? 1 : 0, // vector.y >= 0 ? 1 : 0)) * tile_size`. - let first_tile_crossing = (from_tile_coords + - Vector2I((!vector_is_negative & U32x2::splat(1)).to_i32x2())).to_f32() * tile_size; + let first_tile_crossing = + (from_tile_coords + Vector2I((!vector_is_negative & U32x2::splat(1)).to_i32x2())).to_f32() + * tile_size; let mut t_max = (first_tile_crossing - line_segment.from()) / vector; let t_delta = (tile_size / vector).abs(); @@ -244,11 +270,19 @@ fn process_line_segment(line_segment: LineSegment2F, // // In that case we just need to step in the positive direction to move to the lower // right tile. - if step.x() > 0 { StepDirection::X } else { StepDirection::Y } + if step.x() > 0 { + StepDirection::X + } else { + StepDirection::Y + } }; - let next_t = - (if next_step_direction == StepDirection::X { t_max.x() } else { t_max.y() }).min(1.0); + let next_t = (if next_step_direction == StepDirection::X { + t_max.x() + } else { + t_max.y() + }) + .min(1.0); // If we've reached the end tile, don't step at all. let next_step_direction = if tile_coords == to_tile_coords { @@ -264,13 +298,15 @@ fn process_line_segment(line_segment: LineSegment2F, // Add extra fills if necessary. if step.y() < 0 && next_step_direction == Some(StepDirection::Y) { // Leaves through top boundary. - let auxiliary_segment = LineSegment2F::new(clipped_line_segment.to(), - tile_coords.to_f32() * tile_size); + let auxiliary_segment = + LineSegment2F::new(clipped_line_segment.to(), tile_coords.to_f32() * tile_size); object_builder.add_fill(scene_builder, auxiliary_segment, tile_coords); } else if step.y() > 0 && last_step_direction == Some(StepDirection::Y) { // Enters through top boundary. - let auxiliary_segment = LineSegment2F::new(tile_coords.to_f32() * tile_size, - clipped_line_segment.from()); + let auxiliary_segment = LineSegment2F::new( + tile_coords.to_f32() * tile_size, + clipped_line_segment.from(), + ); object_builder.add_fill(scene_builder, auxiliary_segment, tile_coords); } diff --git a/renderer/src/tiles.rs b/renderer/src/tiles.rs index aa5b80df..ca2f38dd 100644 --- a/renderer/src/tiles.rs +++ b/renderer/src/tiles.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use crate::gpu_data::{TileObjectPrimitive, TILE_CTRL_MASK_WINDING}; use crate::gpu_data::{TILE_CTRL_MASK_0_SHIFT, TILE_CTRL_MASK_EVEN_ODD}; -use crate::gpu_data::{TILE_CTRL_MASK_WINDING, TileObjectPrimitive}; use crate::paint::PaintId; use pathfinder_content::effects::BlendMode; use pathfinder_content::fill::FillRule; @@ -62,10 +62,14 @@ impl TilingPathInfo { } 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() + (rect * vec2f(1.0 / TILE_WIDTH as f32, 1.0 / TILE_HEIGHT as f32)) + .round_out() + .to_i32() } impl TileObjectPrimitive { #[inline] - pub fn is_solid(&self) -> bool { !self.alpha_tile_id.is_valid() } + pub fn is_solid(&self) -> bool { + !self.alpha_tile_id.is_valid() + } } diff --git a/resources/build.rs b/resources/build.rs index 0912c1ad..f5038af8 100644 --- a/resources/build.rs +++ b/resources/build.rs @@ -19,9 +19,16 @@ fn main() { 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(); + 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() { @@ -36,10 +43,12 @@ fn main() { 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(); + writeln!( + &mut dest, + " (\"{}\", include_bytes!(\"{}\")),", + escaped_path, escaped_full_path + ) + .unwrap(); println!("cargo:rerun-if-changed={}", line); } diff --git a/resources/src/embedded.rs b/resources/src/embedded.rs index e9879cde..b4add2ca 100644 --- a/resources/src/embedded.rs +++ b/resources/src/embedded.rs @@ -26,7 +26,11 @@ impl EmbeddedResourceLoader { impl ResourceLoader for EmbeddedResourceLoader { fn slurp(&self, virtual_path: &str) -> Result, IOError> { - match RESOURCES.iter().filter(|&(path, _)| *path == virtual_path).next() { + match RESOURCES + .iter() + .filter(|&(path, _)| *path == virtual_path) + .next() + { Some((_, data)) => Ok(data.to_vec()), None => Err(IOError::from(ErrorKind::NotFound)), } diff --git a/resources/src/lib.rs b/resources/src/lib.rs index 33fe80c5..9300b856 100644 --- a/resources/src/lib.rs +++ b/resources/src/lib.rs @@ -11,10 +11,10 @@ //! 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; diff --git a/simd/src/arm/mod.rs b/simd/src/arm/mod.rs index deed1b7e..53334d8e 100644 --- a/simd/src/arm/mod.rs +++ b/simd/src/arm/mod.rs @@ -10,9 +10,9 @@ use std::arch::aarch64::{self, float32x2_t, float32x4_t, int32x2_t, int32x4_t}; use std::arch::aarch64::{uint32x2_t, uint32x4_t}; -use std::intrinsics::simd::*; use std::f32; use std::fmt::{self, Debug, Formatter}; +use std::intrinsics::simd::*; use std::mem; use std::ops::{Add, BitAnd, BitOr, Div, Index, IndexMut, Mul, Not, Shr, Sub}; @@ -201,7 +201,6 @@ impl IndexMut for F32x2 { } } - impl Add for F32x2 { type Output = F32x2; #[inline] @@ -832,7 +831,6 @@ impl BitOr for U32x2 { } } - // Four 32-bit unsigned integers #[derive(Clone, Copy)] diff --git a/simd/src/extras.rs b/simd/src/extras.rs index c53bbdfa..47a361b2 100644 --- a/simd/src/extras.rs +++ b/simd/src/extras.rs @@ -49,7 +49,10 @@ impl F32x2 { #[inline] pub fn approx_eq(self, other: F32x2, epsilon: f32) -> bool { - (self - other).abs().packed_gt(F32x2::splat(epsilon)).all_false() + (self - other) + .abs() + .packed_gt(F32x2::splat(epsilon)) + .all_false() } } @@ -140,7 +143,10 @@ impl F32x4 { #[inline] pub fn approx_eq(self, other: F32x4, epsilon: f32) -> bool { - (self - other).abs().packed_gt(F32x4::splat(epsilon)).all_false() + (self - other) + .abs() + .packed_gt(F32x4::splat(epsilon)) + .all_false() } } diff --git a/simd/src/scalar/mod.rs b/simd/src/scalar/mod.rs index 601d70d0..f0182c96 100644 --- a/simd/src/scalar/mod.rs +++ b/simd/src/scalar/mod.rs @@ -10,7 +10,7 @@ use std::f32; use std::fmt::{self, Debug, Formatter}; -use std::ops::{Add, BitAnd, BitOr, Div, Index, IndexMut, Mul, Shr, Sub, Not}; +use std::ops::{Add, BitAnd, BitOr, Div, Index, IndexMut, Mul, Not, Shr, Sub}; mod swizzle_f32x4; mod swizzle_i32x4; @@ -485,18 +485,12 @@ impl I32x2 { #[inline] pub fn min(self, other: I32x2) -> I32x2 { - I32x2([ - self[0].min(other[0]), - self[1].min(other[1]), - ]) + 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]), - ]) + I32x2([self[0].max(other[0]), self[1].max(other[1])]) } // Packed comparisons @@ -531,7 +525,7 @@ impl I32x2 { if self[0] < other[0] { !0 } else { 0 }, if self[1] < other[1] { !0 } else { 0 }, ]) - } + } // Conversions @@ -715,7 +709,12 @@ impl I32x4 { /// 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]) + U32x4([ + self[0] as u32, + self[1] as u32, + self[2] as u32, + self[3] as u32, + ]) } } @@ -777,7 +776,12 @@ 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]]) + I32x4([ + self[0] & other[0], + self[1] & other[1], + self[2] & other[2], + self[3] & other[3], + ]) } } @@ -785,7 +789,12 @@ 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]]) + I32x4([ + self[0] | other[0], + self[1] | other[1], + self[2] | other[2], + self[3] | other[3], + ]) } } @@ -840,7 +849,6 @@ impl U32x2 { pub fn to_i32x2(self) -> I32x2 { I32x2::new(self[0] as i32, self[1] as i32) } - } impl BitAnd for U32x2 { @@ -894,7 +902,12 @@ impl U32x4 { /// 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]) + I32x4([ + self[0] as i32, + self[1] as i32, + self[2] as i32, + self[3] as i32, + ]) } // Basic operations @@ -930,6 +943,11 @@ 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]) + U32x4([ + self[0] >> amount, + self[1] >> amount, + self[2] >> amount, + self[3] >> amount, + ]) } } diff --git a/simd/src/test.rs b/simd/src/test.rs index 07d45513..618bb503 100644 --- a/simd/src/test.rs +++ b/simd/src/test.rs @@ -37,7 +37,10 @@ fn test_f32x4_accessors_and_mutators() { 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.333313, 0.19995117, 0.14282227)); + assert_eq!( + a.approx_recip(), + F32x4::new(0.99975586, 0.333313, 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); diff --git a/simd/src/x86/mod.rs b/simd/src/x86/mod.rs index e2702856..3623ac5e 100644 --- a/simd/src/x86/mod.rs +++ b/simd/src/x86/mod.rs @@ -13,14 +13,14 @@ 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 = "32")] +use std::arch::x86::{__m128, __m128i}; #[cfg(target_pointer_width = "64")] use std::arch::x86_64 as x86; +#[cfg(target_pointer_width = "64")] +use std::arch::x86_64::{__m128, __m128i}; mod swizzle_f32x4; mod swizzle_i32x4; @@ -285,20 +285,12 @@ impl F32x4 { #[inline] pub fn packed_eq(self, other: F32x4) -> U32x4 { - unsafe { - U32x4(x86::_mm_castps_si128(x86::_mm_cmpeq_ps( - self.0, other.0, - ))) - } + 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, - ))) - } + unsafe { U32x4(x86::_mm_castps_si128(x86::_mm_cmpgt_ps(self.0, other.0))) } } #[inline] diff --git a/simd/src/x86/swizzle_i32x4.rs b/simd/src/x86/swizzle_i32x4.rs index 0743d2e1..1991ed97 100644 --- a/simd/src/x86/swizzle_i32x4.rs +++ b/simd/src/x86/swizzle_i32x4.rs @@ -20,9 +20,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 0))) } } @@ -30,9 +28,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 1))) } } @@ -40,9 +36,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 2))) } } @@ -50,9 +44,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 3))) } } @@ -60,9 +52,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 4))) } } @@ -70,9 +60,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 5))) } } @@ -80,9 +68,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 6))) } } @@ -90,9 +76,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 7))) } } @@ -100,9 +84,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 8))) } } @@ -110,9 +92,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 9))) } } @@ -120,9 +100,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 10))) } } @@ -130,9 +108,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 11))) } } @@ -140,9 +116,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 12))) } } @@ -150,9 +124,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 13))) } } @@ -160,9 +132,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 14))) } } @@ -170,9 +140,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 15))) } } @@ -180,9 +148,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 16))) } } @@ -190,9 +156,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 17))) } } @@ -200,9 +164,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 18))) } } @@ -210,9 +172,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 19))) } } @@ -220,9 +180,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 20))) } } @@ -230,9 +188,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 21))) } } @@ -240,9 +196,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 22))) } } @@ -250,9 +204,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 23))) } } @@ -260,9 +212,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 24))) } } @@ -270,9 +220,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 25))) } } @@ -280,9 +228,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 26))) } } @@ -290,9 +236,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 27))) } } @@ -300,9 +244,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 28))) } } @@ -310,9 +252,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 29))) } } @@ -320,9 +260,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 30))) } } @@ -330,9 +268,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 31))) } } @@ -340,9 +276,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 32))) } } @@ -350,9 +284,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 33))) } } @@ -360,9 +292,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 34))) } } @@ -370,9 +300,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 35))) } } @@ -380,9 +308,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 36))) } } @@ -390,9 +316,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 37))) } } @@ -400,9 +324,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 38))) } } @@ -410,9 +332,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 39))) } } @@ -420,9 +340,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 40))) } } @@ -430,9 +348,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 41))) } } @@ -440,9 +356,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 42))) } } @@ -450,9 +364,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 43))) } } @@ -460,9 +372,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 44))) } } @@ -470,9 +380,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 45))) } } @@ -480,9 +388,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 46))) } } @@ -490,9 +396,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 47))) } } @@ -500,9 +404,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 48))) } } @@ -510,9 +412,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 49))) } } @@ -520,9 +420,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 50))) } } @@ -530,9 +428,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 51))) } } @@ -540,9 +436,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 52))) } } @@ -550,9 +444,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 53))) } } @@ -560,9 +452,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 54))) } } @@ -570,9 +460,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 55))) } } @@ -580,9 +468,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 56))) } } @@ -590,9 +476,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 57))) } } @@ -600,9 +484,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 58))) } } @@ -610,9 +492,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 59))) } } @@ -620,9 +500,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 60))) } } @@ -630,9 +508,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 61))) } } @@ -640,9 +516,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 62))) } } @@ -650,9 +524,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 63))) } } @@ -660,9 +532,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 64))) } } @@ -670,9 +540,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 65))) } } @@ -680,9 +548,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 66))) } } @@ -690,9 +556,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 67))) } } @@ -700,9 +564,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 68))) } } @@ -710,9 +572,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 69))) } } @@ -720,9 +580,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 70))) } } @@ -730,9 +588,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 71))) } } @@ -740,9 +596,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 72))) } } @@ -750,9 +604,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 73))) } } @@ -760,9 +612,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 74))) } } @@ -770,9 +620,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 75))) } } @@ -780,9 +628,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 76))) } } @@ -790,9 +636,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 77))) } } @@ -800,9 +644,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 78))) } } @@ -810,9 +652,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 79))) } } @@ -820,9 +660,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 80))) } } @@ -830,9 +668,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 81))) } } @@ -840,9 +676,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 82))) } } @@ -850,9 +684,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 83))) } } @@ -860,9 +692,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 84))) } } @@ -870,9 +700,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 85))) } } @@ -880,9 +708,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 86))) } } @@ -890,9 +716,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 87))) } } @@ -900,9 +724,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 88))) } } @@ -910,9 +732,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 89))) } } @@ -920,9 +740,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 90))) } } @@ -930,9 +748,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 91))) } } @@ -940,9 +756,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 92))) } } @@ -950,9 +764,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 93))) } } @@ -960,9 +772,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 94))) } } @@ -970,9 +780,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 95))) } } @@ -980,9 +788,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 96))) } } @@ -990,9 +796,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 97))) } } @@ -1000,9 +804,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 98))) } } @@ -1010,9 +812,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 99))) } } @@ -1020,9 +820,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 100))) } } @@ -1030,9 +828,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 101))) } } @@ -1040,9 +836,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 102))) } } @@ -1050,9 +844,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 103))) } } @@ -1060,9 +852,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 104))) } } @@ -1070,9 +860,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 105))) } } @@ -1080,9 +868,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 106))) } } @@ -1090,9 +876,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 107))) } } @@ -1100,9 +884,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 108))) } } @@ -1110,9 +892,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 109))) } } @@ -1120,9 +900,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 110))) } } @@ -1130,9 +908,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 111))) } } @@ -1140,9 +916,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 112))) } } @@ -1150,9 +924,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 113))) } } @@ -1160,9 +932,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 114))) } } @@ -1170,9 +940,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 115))) } } @@ -1180,9 +948,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 116))) } } @@ -1190,9 +956,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 117))) } } @@ -1200,9 +964,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 118))) } } @@ -1210,9 +972,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 119))) } } @@ -1220,9 +980,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 120))) } } @@ -1230,9 +988,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 121))) } } @@ -1240,9 +996,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 122))) } } @@ -1250,9 +1004,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 123))) } } @@ -1260,9 +1012,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 124))) } } @@ -1270,9 +1020,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 125))) } } @@ -1280,9 +1028,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 126))) } } @@ -1290,9 +1036,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 127))) } } @@ -1300,9 +1044,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 128))) } } @@ -1310,9 +1052,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 129))) } } @@ -1320,9 +1060,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 130))) } } @@ -1330,9 +1068,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 131))) } } @@ -1340,9 +1076,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 132))) } } @@ -1350,9 +1084,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 133))) } } @@ -1360,9 +1092,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 134))) } } @@ -1370,9 +1100,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 135))) } } @@ -1380,9 +1108,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 136))) } } @@ -1390,9 +1116,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 137))) } } @@ -1400,9 +1124,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 138))) } } @@ -1410,9 +1132,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 139))) } } @@ -1420,9 +1140,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 140))) } } @@ -1430,9 +1148,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 141))) } } @@ -1440,9 +1156,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 142))) } } @@ -1450,9 +1164,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 143))) } } @@ -1460,9 +1172,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 144))) } } @@ -1470,9 +1180,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 145))) } } @@ -1480,9 +1188,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 146))) } } @@ -1490,9 +1196,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 147))) } } @@ -1500,9 +1204,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 148))) } } @@ -1510,9 +1212,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 149))) } } @@ -1520,9 +1220,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 150))) } } @@ -1530,9 +1228,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 151))) } } @@ -1540,9 +1236,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 152))) } } @@ -1550,9 +1244,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 153))) } } @@ -1560,9 +1252,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 154))) } } @@ -1570,9 +1260,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 155))) } } @@ -1580,9 +1268,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 156))) } } @@ -1590,9 +1276,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 157))) } } @@ -1600,9 +1284,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 158))) } } @@ -1610,9 +1292,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 159))) } } @@ -1620,9 +1300,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 160))) } } @@ -1630,9 +1308,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 161))) } } @@ -1640,9 +1316,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 162))) } } @@ -1650,9 +1324,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 163))) } } @@ -1660,9 +1332,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 164))) } } @@ -1670,9 +1340,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 165))) } } @@ -1680,9 +1348,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 166))) } } @@ -1690,9 +1356,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 167))) } } @@ -1700,9 +1364,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 168))) } } @@ -1710,9 +1372,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 169))) } } @@ -1720,9 +1380,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 170))) } } @@ -1730,9 +1388,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 171))) } } @@ -1740,9 +1396,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 172))) } } @@ -1750,9 +1404,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 173))) } } @@ -1760,9 +1412,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 174))) } } @@ -1770,9 +1420,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 175))) } } @@ -1780,9 +1428,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 176))) } } @@ -1790,9 +1436,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 177))) } } @@ -1800,9 +1444,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 178))) } } @@ -1810,9 +1452,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 179))) } } @@ -1820,9 +1460,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 180))) } } @@ -1830,9 +1468,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 181))) } } @@ -1840,9 +1476,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 182))) } } @@ -1850,9 +1484,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 183))) } } @@ -1860,9 +1492,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 184))) } } @@ -1870,9 +1500,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 185))) } } @@ -1880,9 +1508,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 186))) } } @@ -1890,9 +1516,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 187))) } } @@ -1900,9 +1524,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 188))) } } @@ -1910,9 +1532,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 189))) } } @@ -1920,9 +1540,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 190))) } } @@ -1930,9 +1548,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 191))) } } @@ -1940,9 +1556,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 192))) } } @@ -1950,9 +1564,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 193))) } } @@ -1960,9 +1572,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 194))) } } @@ -1970,9 +1580,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 195))) } } @@ -1980,9 +1588,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 196))) } } @@ -1990,9 +1596,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 197))) } } @@ -2000,9 +1604,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 198))) } } @@ -2010,9 +1612,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 199))) } } @@ -2020,9 +1620,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 200))) } } @@ -2030,9 +1628,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 201))) } } @@ -2040,9 +1636,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 202))) } } @@ -2050,9 +1644,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 203))) } } @@ -2060,9 +1652,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 204))) } } @@ -2070,9 +1660,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 205))) } } @@ -2080,9 +1668,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 206))) } } @@ -2090,9 +1676,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 207))) } } @@ -2100,9 +1684,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 208))) } } @@ -2110,9 +1692,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 209))) } } @@ -2120,9 +1700,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 210))) } } @@ -2130,9 +1708,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 211))) } } @@ -2140,9 +1716,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 212))) } } @@ -2150,9 +1724,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 213))) } } @@ -2160,9 +1732,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 214))) } } @@ -2170,9 +1740,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 215))) } } @@ -2180,9 +1748,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 216))) } } @@ -2190,9 +1756,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 217))) } } @@ -2200,9 +1764,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 218))) } } @@ -2210,9 +1772,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 219))) } } @@ -2220,9 +1780,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 220))) } } @@ -2230,9 +1788,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 221))) } } @@ -2240,9 +1796,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 222))) } } @@ -2250,9 +1804,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 223))) } } @@ -2260,9 +1812,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 224))) } } @@ -2270,9 +1820,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 225))) } } @@ -2280,9 +1828,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 226))) } } @@ -2290,9 +1836,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 227))) } } @@ -2300,9 +1844,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 228))) } } @@ -2310,9 +1852,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 229))) } } @@ -2320,9 +1860,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 230))) } } @@ -2330,9 +1868,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 231))) } } @@ -2340,9 +1876,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 232))) } } @@ -2350,9 +1884,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 233))) } } @@ -2360,9 +1892,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 234))) } } @@ -2370,9 +1900,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 235))) } } @@ -2380,9 +1908,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 236))) } } @@ -2390,9 +1916,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 237))) } } @@ -2400,9 +1924,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 238))) } } @@ -2410,9 +1932,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 239))) } } @@ -2420,9 +1940,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 240))) } } @@ -2430,9 +1948,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 241))) } } @@ -2440,9 +1956,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 242))) } } @@ -2450,9 +1964,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 243))) } } @@ -2460,9 +1972,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 244))) } } @@ -2470,9 +1980,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 245))) } } @@ -2480,9 +1988,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 246))) } } @@ -2490,9 +1996,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 247))) } } @@ -2500,9 +2004,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 248))) } } @@ -2510,9 +2012,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 249))) } } @@ -2520,9 +2020,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 250))) } } @@ -2530,9 +2028,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 251))) } } @@ -2540,9 +2036,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 252))) } } @@ -2550,9 +2044,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 253))) } } @@ -2560,9 +2052,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 254))) } } @@ -2570,9 +2060,7 @@ impl I32x4 { 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, - ))) + I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(this, this, 255))) } } } diff --git a/svg/Cargo.toml b/svg/Cargo.toml index 425fd908..1c7d1626 100644 --- a/svg/Cargo.toml +++ b/svg/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["pathfinder", "svg", "vector", "graphics", "gpu"] [dependencies] bitflags = "1.0" hashbrown = "0.7" -usvg = "0.9" +usvg = "0.10.0" [dependencies.pathfinder_color] path = "../color" diff --git a/svg/src/lib.rs b/svg/src/lib.rs index 71185ef9..d288cd02 100644 --- a/svg/src/lib.rs +++ b/svg/src/lib.rs @@ -25,7 +25,7 @@ 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_geometry::vector::{vec2f, Vector2F}; use pathfinder_renderer::paint::Paint; use pathfinder_renderer::scene::{ClipPath, ClipPathId, DrawPath, Scene}; use pathfinder_simd::default::F32x2; @@ -80,7 +80,9 @@ impl SVGScene { 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)); + 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); } @@ -91,24 +93,24 @@ impl SVGScene { built_svg } - fn process_node(&mut self, - node: &Node, - state: &State, - clip_outline: &mut Option) { + 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 = state.transform * node_transform; match *node.borrow() { NodeKind::Group(ref group) => { if group.filter.is_some() { - self.result_flags.insert(BuildResultFlags::UNSUPPORTED_FILTER_ATTR); + self.result_flags + .insert(BuildResultFlags::UNSUPPORTED_FILTER_ATTR); } if group.mask.is_some() { - self.result_flags.insert(BuildResultFlags::UNSUPPORTED_MASK_ATTR); + self.result_flags + .insert(BuildResultFlags::UNSUPPORTED_MASK_ATTR); } if let Some(ref clip_path_name) = group.clip_path { if let Some(clip_outline) = self.clip_paths.get(clip_path_name) { - let transformed_outline = clip_outline.clone().transformed(&state.transform); + let transformed_outline = + clip_outline.clone().transformed(&state.transform); let mut clip_path = ClipPath::new(transformed_outline); clip_path.set_clip_path(state.clip_path); clip_path.set_name(format!("ClipPath({})", clip_path_name)); @@ -126,31 +128,38 @@ impl SVGScene { 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); + 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 => { + 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); + 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), + line_join: LineJoin::from_usvg_line_join( + stroke.linejoin, + stroke.miterlimit.value() as f32, + ), }; let path = UsvgPathToSegments::new(path.data.iter().cloned()); @@ -168,12 +177,14 @@ impl SVGScene { 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); + self.push_draw_path( + outline, + name, + &state, + &stroke.paint, + stroke.opacity, + UsvgFillRule::NonZero, + ); } } NodeKind::Path(..) => {} @@ -184,7 +195,8 @@ impl SVGScene { self.process_node(&kid, &state, &mut clip_outline); } - self.clip_paths.insert(node.id().to_owned(), clip_outline.unwrap()); + self.clip_paths + .insert(node.id().to_owned(), clip_outline.unwrap()); } NodeKind::Defs => { // FIXME(pcwalton): This is wrong. @@ -195,20 +207,24 @@ impl SVGScene { } 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 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) + 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 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) + self.add_gradient( + gradient, + svg_radial_gradient.id.clone(), + &svg_radial_gradient.base, + ) } NodeKind::Filter(..) => { self.result_flags @@ -230,10 +246,12 @@ impl SVGScene { } } - fn add_gradient(&mut self, - mut gradient: Gradient, - id: String, - usvg_base_gradient: &BaseGradient) { + fn add_gradient( + &mut self, + mut gradient: Gradient, + id: String, + usvg_base_gradient: &BaseGradient, + ) { for stop in &usvg_base_gradient.stops { let mut stop = ColorStop::from_usvg_stop(stop); if usvg_base_gradient.spread_method == SpreadMethod::Reflect { @@ -261,22 +279,32 @@ impl SVGScene { 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 }); + 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) { + 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 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); @@ -323,22 +351,24 @@ impl Display for BuildResultFlags { } trait PaintExt { - fn from_svg_paint(svg_paint: &UsvgPaint, - transform: &Transform2F, - opacity: Opacity, - gradients: &HashMap, - result_flags: &mut BuildResultFlags) - -> Self; + 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 { + 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)), @@ -366,13 +396,21 @@ impl PaintExt for 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)) + 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) + 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 @@ -435,8 +473,10 @@ where 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)); + 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); } @@ -465,7 +505,12 @@ trait ColorUExt { 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 } + ColorU { + r: svg_color.red, + g: svg_color.green, + b: svg_color.blue, + a: !0, + } } } diff --git a/swf/src/lib.rs b/swf/src/lib.rs index 39c5593a..63b7c96d 100644 --- a/swf/src/lib.rs +++ b/swf/src/lib.rs @@ -8,16 +8,16 @@ // 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::outline::{Contour, Outline}; use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle}; use pathfinder_geometry::vector::vec2f; use pathfinder_renderer::scene::{DrawPath, Scene}; +use std::ops::Add; use swf_types::tags::SetBackgroundColor; -use swf_types::{Tag, SRgb8, Movie}; +use swf_types::{Movie, SRgb8, Tag}; use crate::shapes::{GraphicLayers, PaintOrLine}; @@ -51,7 +51,7 @@ impl Add for Twips { #[derive(Copy, Clone, Debug, PartialEq)] struct Point2 { x: T, - y: T + y: T, } impl Point2 { @@ -66,7 +66,10 @@ impl Point2 { impl Add for Point2 { type Output = Self; fn add(self, rhs: Self) -> Self { - Point2 { x: self.x + rhs.x, y: self.y + rhs.y } + Point2 { + x: self.x + rhs.x, + y: self.y + rhs.y, + } } } @@ -98,11 +101,11 @@ impl Stage { g: self.background_color.g, b: self.background_color.b, a: 255, - }.to_f32() + } + .to_f32() } } - pub struct SymbolLibrary(Vec); impl SymbolLibrary { @@ -126,7 +129,7 @@ pub fn process_swf_tags(movie: &Movie) -> (SymbolLibrary, Stage) { background_color: SRgb8 { r: 255, g: 255, - b: 255 + b: 255, }, width: stage_width.as_f32() as i32, height: stage_height.as_f32() as i32, @@ -136,14 +139,14 @@ pub fn process_swf_tags(movie: &Movie) -> (SymbolLibrary, Stage) { 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) @@ -166,12 +169,15 @@ pub fn draw_paths_into_scene(library: &SymbolLibrary, scene: &mut Scene) { let Point2 { x, y } = segment.to.as_f32(); match segment.ctrl { Some(ctrl) => { - let Point2 { x: ctrl_x, y: ctrl_y } = ctrl.as_f32(); + 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() { @@ -183,11 +189,14 @@ pub fn draw_paths_into_scene(library: &SymbolLibrary, scene: &mut Scene) { } 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, - }); + 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(); } diff --git a/swf/src/shapes.rs b/swf/src/shapes.rs index 88b45178..06dc4318 100644 --- a/swf/src/shapes.rs +++ b/swf/src/shapes.rs @@ -8,16 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::{Twips, Point2}; +use crate::{Point2, Twips}; use pathfinder_color::ColorU; -use pathfinder_content::stroke::{LineJoin, LineCap}; +use pathfinder_content::stroke::{LineCap, LineJoin}; 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}; +use swf_types::{CapStyle, FillStyle, JoinStyle, LineStyle, ShapeRecord, StraightSRgba8, Vector2D}; #[derive(Clone, Copy, Debug)] pub(crate) struct LineSegment { @@ -44,7 +44,7 @@ impl LineDirection { fn reverse(&mut self) { *self = match self { LineDirection::Right => LineDirection::Left, - LineDirection::Left => LineDirection::Right + LineDirection::Left => LineDirection::Right, }; } } @@ -194,19 +194,16 @@ impl StyleLayer { 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()) { + 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()); + 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 { @@ -235,78 +232,75 @@ impl StyleLayer { } } - fn get_new_styles<'a>( fills: &'a Vec, - lines: &'a Vec -) -> impl Iterator + 'a { + 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"); - } + 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 { @@ -339,15 +333,13 @@ pub(crate) fn decode_shape(shape: &DefineShape) -> GraphicLayers { for record in &shape.records { match record { - ShapeRecord::StyleChange( - shape_records::StyleChange { - move_to, - new_styles, - line_style, - left_fill, - right_fill, - } - ) => { + 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. @@ -406,7 +398,10 @@ pub(crate) fn decode_shape(shape: &DefineShape) -> GraphicLayers { // 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) }; + 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 @@ -433,34 +428,27 @@ pub(crate) fn decode_shape(shape: &DefineShape) -> GraphicLayers { .push_new_shape(LineDirection::Right); } } - }, - ShapeRecord::Edge( - shape_records::Edge { - delta, - control_delta, - } - ) => { + } + 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) + 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), - } + 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() { + 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) @@ -472,8 +460,10 @@ pub(crate) fn decode_shape(shape: &DefineShape) -> GraphicLayers { } else if both_fills_set_and_same { for (fill_id, direction) in [ (current_right_fill, LineDirection::Right), - (current_left_fill, LineDirection::Left) - ].iter() { + (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 @@ -508,7 +498,7 @@ pub(crate) fn decode_shape(shape: &DefineShape) -> GraphicLayers { fn find_matches( mut first_open_index: usize, shapes: &mut Vec, - reverse: bool + reverse: bool, ) -> Option> { let mut dropped_pieces = None; while first_open_index < shapes.len() { @@ -563,7 +553,11 @@ pub(crate) struct GraphicLayers { impl GraphicLayers { fn new() -> GraphicLayers { - GraphicLayers { style_layers: Vec::new(), stroke_layer_offset: None, base_layer_offset: 0 } + GraphicLayers { + style_layers: Vec::new(), + stroke_layer_offset: None, + base_layer_offset: 0, + } } fn begin_style_group(&mut self) { @@ -572,22 +566,30 @@ impl GraphicLayers { } fn begin_fill_style(&mut self, fill: Paint) { - self.style_layers.push(StyleLayer { fill: PaintOrLine::Paint(fill), shapes: Vec::new() }) + 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() }) + 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) + 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) + self.style_layers + .get_mut((self.stroke_layer_offset.unwrap() + line_id) - 1) } pub(crate) fn layers(&self) -> &Vec { @@ -606,4 +608,3 @@ impl GraphicLayers { } } } - diff --git a/text/Cargo.toml b/text/Cargo.toml index 3c5c1135..eefe7839 100644 --- a/text/Cargo.toml +++ b/text/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/servo/pathfinder" homepage = "https://github.com/servo/pathfinder" [dependencies] -font-kit = "0.6" +font-kit = "0.13" [dependencies.pathfinder_content] path = "../content" diff --git a/text/src/lib.rs b/text/src/lib.rs index b3e6cf24..cb334be6 100644 --- a/text/src/lib.rs +++ b/text/src/lib.rs @@ -19,7 +19,7 @@ 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_geometry::vector::{vec2f, Vector2F}; use pathfinder_renderer::paint::PaintId; use pathfinder_renderer::scene::{ClipPathId, DrawPath, Scene}; use skribo::{FontCollection, Layout, TextStyle}; @@ -28,12 +28,18 @@ use std::mem; use std::sync::Arc; #[derive(Clone)] -pub struct FontContext where F: Loader { - font_info: HashMap>, +pub struct FontContext +where + F: Loader, +{ + font_info: HashMap>, } #[derive(Clone)] -struct FontInfo where F: Loader { +struct FontInfo +where + F: Loader, +{ font: F, metrics: Metrics, outline_cache: HashMap, @@ -63,7 +69,10 @@ impl Default for FontRenderOptions { } } -enum FontInfoRefMut<'a, F> where F: Loader { +enum FontInfoRefMut<'a, F> +where + F: Loader, +{ Ref(&'a mut FontInfo), Owned(FontInfo), } @@ -71,26 +80,33 @@ enum FontInfoRefMut<'a, F> where F: Loader { #[derive(Clone, Copy, PartialEq, Debug, Eq, Hash)] pub struct GlyphId(pub u32); -impl FontContext where F: Loader { +impl FontContext +where + F: Loader, +{ #[inline] pub fn new() -> FontContext { - FontContext { font_info: HashMap::new() } + FontContext { + font_info: HashMap::new(), + } } - fn push_glyph(&mut self, - scene: &mut Scene, - font: &F, - font_key: Option<&str>, - glyph_id: GlyphId, - glyph_offset: Vector2F, - font_size: f32, - render_options: &FontRenderOptions) - -> Result<(), GlyphLoadingError> { + fn push_glyph( + &mut self, + scene: &mut Scene, + font: &F, + font_key: Option<&str>, + glyph_id: GlyphId, + glyph_offset: Vector2F, + font_size: f32, + render_options: &FontRenderOptions, + ) -> Result<(), GlyphLoadingError> { // Insert the font into the cache if needed. let mut font_info = match font_key { Some(font_key) => { if !self.font_info.contains_key(&*font_key) { - self.font_info.insert(font_key.to_owned(), FontInfo::new((*font).clone())); + self.font_info + .insert(font_key.to_owned(), FontInfo::new((*font).clone())); } FontInfoRefMut::Ref(self.font_info.get_mut(&*font_key).unwrap()) } @@ -115,8 +131,8 @@ impl FontContext where F: Loader { let metrics = &font_info.metrics; let font_scale = font_size / metrics.units_per_em as f32; - let render_transform = render_options.transform * - Transform2F::from_scale(vec2f(font_scale, -font_scale)).translate(glyph_offset); + let render_transform = render_options.transform + * Transform2F::from_scale(vec2f(font_scale, -font_scale)).translate(glyph_offset); let mut outline = match cached_outline { Some(mut cached_outline) => { @@ -131,7 +147,11 @@ impl FontContext where F: Loader { render_transform }; let mut outline_builder = OutlinePathBuilder::new(&transform); - font.outline(glyph_id.0, render_options.hinting_options, &mut outline_builder)?; + font.outline( + glyph_id.0, + render_options.hinting_options, + &mut outline_builder, + )?; let mut outline = outline_builder.build(); if can_cache_outline { font_info.outline_cache.insert(glyph_id, outline.clone()); @@ -159,22 +179,25 @@ impl FontContext where F: Loader { /// 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) + 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> { + pub fn push_layout( + &mut self, + scene: &mut Scene, + layout: &Layout, + style: &TextStyle, + render_options: &FontRenderOptions, + ) -> Result<(), GlyphLoadingError> { let mut cached_font_key: Option> = None; for glyph in &layout.glyphs { match cached_font_key { - Some(ref cached_font_key) if Arc::ptr_eq(&cached_font_key.font, - &glyph.font.font) => {} + Some(ref cached_font_key) + if Arc::ptr_eq(&cached_font_key.font, &glyph.font.font) => {} _ => { cached_font_key = Some(CachedFontKey { font: glyph.font.font.clone(), @@ -183,43 +206,59 @@ impl FontContext { } } let cached_font_key = cached_font_key.as_ref().unwrap(); - self.push_glyph(scene, - &*cached_font_key.font, - cached_font_key.key.as_ref().map(|key| &**key), - GlyphId(glyph.glyph_id), - glyph.offset, - style.size, - &render_options)?; + self.push_glyph( + scene, + &*cached_font_key.font, + cached_font_key.key.as_ref().map(|key| &**key), + GlyphId(glyph.glyph_id), + glyph.offset, + style.size, + &render_options, + )?; } Ok(()) } #[inline] - pub fn push_text(&mut self, - scene: &mut Scene, - text: &str, - style: &TextStyle, - collection: &FontCollection, - render_options: &FontRenderOptions) - -> Result<(), GlyphLoadingError> { + 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) } } -struct CachedFontKey where F: Loader { +struct CachedFontKey +where + F: Loader, +{ font: Arc, key: Option, } -impl FontInfo where F: Loader { +impl FontInfo +where + F: Loader, +{ fn new(font: F) -> FontInfo { let metrics = font.metrics(); - FontInfo { font, metrics, outline_cache: HashMap::new() } + FontInfo { + font, + metrics, + outline_cache: HashMap::new(), + } } } -impl<'a, F> FontInfoRefMut<'a, F> where F: Loader { +impl<'a, F> FontInfoRefMut<'a, F> +where + F: Loader, +{ fn get_mut(&mut self) -> &mut FontInfo { match *self { FontInfoRefMut::Ref(ref mut reference) => &mut **reference, @@ -251,7 +290,8 @@ impl OutlinePathBuilder { fn flush_current_contour(&mut self) { if !self.current_contour.is_empty() { - self.outline.push_contour(mem::replace(&mut self.current_contour, Contour::new())); + self.outline + .push_contour(mem::replace(&mut self.current_contour, Contour::new())); } } @@ -272,13 +312,16 @@ impl OutlineSink for OutlinePathBuilder { } fn quadratic_curve_to(&mut self, ctrl: Vector2F, to: Vector2F) { - self.current_contour.push_quadratic(self.transform * ctrl, self.transform * to); + 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); + self.current_contour.push_cubic( + self.transform * ctrl.from(), + self.transform * ctrl.to(), + self.transform * to, + ); } fn close(&mut self) { diff --git a/ui/src/lib.rs b/ui/src/lib.rs index dc4bf940..de663901 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -19,7 +19,7 @@ extern crate serde_derive; use hashbrown::HashMap; use pathfinder_color::ColorU; use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2i}; +use pathfinder_geometry::vector::{vec2i, Vector2F, Vector2I}; use pathfinder_gpu::allocator::{BufferTag, GPUMemoryAllocator}; use pathfinder_gpu::{BlendFactor, BlendState, BufferTarget, Device, Primitive, RenderOptions}; use pathfinder_gpu::{RenderState, RenderTarget, TextureFormat, UniformData, VertexAttrClass}; @@ -41,19 +41,44 @@ 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 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 }; +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 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 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"; @@ -61,11 +86,14 @@ 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 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 struct UIPresenter +where + D: Device, +{ pub event_queue: UIEventQueue, pub mouse_position: Vector2F, @@ -80,23 +108,26 @@ pub struct UIPresenter where D: Device { corner_outline_texture: D::Texture, } -impl UIPresenter where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader, framebuffer_size: Vector2I) - -> UIPresenter { +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 font = DebugFont::load(resources); let solid_program = DebugSolidProgram::new(device, resources); - 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); + 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(), @@ -122,29 +153,34 @@ impl UIPresenter where D: Device { self.framebuffer_size = window_size; } - - pub fn draw_solid_rect(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - rect: RectI, - color: ColorU) { + pub fn draw_solid_rect( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + rect: RectI, + color: ColorU, + ) { self.draw_rect(device, allocator, rect, color, true); } - pub fn draw_rect_outline(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - rect: RectI, - color: ColorU) { + pub fn draw_rect_outline( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + rect: RectI, + color: ColorU, + ) { self.draw_rect(device, allocator, rect, color, false); } - fn draw_rect(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - rect: RectI, - color: ColorU, - filled: bool) { + fn draw_rect( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + rect: RectI, + color: ColorU, + filled: bool, + ) { let vertex_data = [ DebugSolidVertex::new(rect.origin()), DebugSolidVertex::new(rect.upper_right()), @@ -153,78 +189,100 @@ impl UIPresenter where D: Device { ]; if filled { - self.draw_solid_rects_with_vertex_data(device, - allocator, - &vertex_data, - &QUAD_INDICES, - color, - true); + self.draw_solid_rects_with_vertex_data( + device, + allocator, + &vertex_data, + &QUAD_INDICES, + color, + true, + ); } else { - self.draw_solid_rects_with_vertex_data(device, - allocator, - &vertex_data, - &RECT_LINE_INDICES, - color, - false); + self.draw_solid_rects_with_vertex_data( + device, + allocator, + &vertex_data, + &RECT_LINE_INDICES, + color, + false, + ); } } - fn draw_solid_rects_with_vertex_data(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - vertex_data: &[DebugSolidVertex], - index_data: &[u32], - color: ColorU, - filled: bool) { - let vertex_buffer_id = - allocator.allocate_general_buffer::(device, - vertex_data.len() as u64, - BufferTag("SolidVertexDebug")); - let index_buffer_id = allocator.allocate_index_buffer::(device, - index_data.len() as u64, - BufferTag("SolidIndexDebug")); + fn draw_solid_rects_with_vertex_data( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + vertex_data: &[DebugSolidVertex], + index_data: &[u32], + color: ColorU, + filled: bool, + ) { + let vertex_buffer_id = allocator.allocate_general_buffer::( + device, + vertex_data.len() as u64, + BufferTag("SolidVertexDebug"), + ); + let index_buffer_id = allocator.allocate_index_buffer::( + device, + index_data.len() as u64, + BufferTag("SolidIndexDebug"), + ); { let vertex_buffer = allocator.get_general_buffer(vertex_buffer_id); let index_buffer = allocator.get_index_buffer(index_buffer_id); device.upload_to_buffer(&vertex_buffer, 0, vertex_data, BufferTarget::Vertex); device.upload_to_buffer(&index_buffer, 0, index_data, BufferTarget::Index); - let solid_vertex_array = DebugSolidVertexArray::new(device, - &self.solid_program, - vertex_buffer, - index_buffer); + let solid_vertex_array = DebugSolidVertexArray::new( + device, + &self.solid_program, + vertex_buffer, + index_buffer, + ); - 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: &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: &[], - storage_buffers: &[], - viewport: RectI::new(Vector2I::default(), self.framebuffer_size), - options: RenderOptions { - blend: Some(alpha_blend_state()), - ..RenderOptions::default() + 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: &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: &[], + storage_buffers: &[], + viewport: RectI::new(Vector2I::default(), self.framebuffer_size), + options: RenderOptions { + blend: Some(alpha_blend_state()), + ..RenderOptions::default() + }, }, - }); + ); } allocator.free_index_buffer(index_buffer_id); allocator.free_general_buffer(vertex_buffer_id); } - pub fn draw_text(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - string: &str, - origin: Vector2I, - invert: bool) { + pub fn draw_text( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + 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); @@ -235,16 +293,17 @@ impl UIPresenter where D: Device { } 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 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.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()), + 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)); @@ -252,36 +311,46 @@ impl UIPresenter where D: Device { next.set_x(next_x); } - let color = if invert { INVERTED_TEXT_COLOR } else { TEXT_COLOR }; - self.draw_texture_with_vertex_data(device, - allocator, - &vertex_data, - &index_data, - &self.font_texture, - color); + let color = if invert { + INVERTED_TEXT_COLOR + } else { + TEXT_COLOR + }; + self.draw_texture_with_vertex_data( + device, + allocator, + &vertex_data, + &index_data, + &self.font_texture, + color, + ); } - pub fn draw_texture(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - origin: Vector2I, - texture: &D::Texture, - color: ColorU) { + pub fn draw_texture( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + 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.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()), + DebugTextureVertex::new(position_rect.lower_left(), tex_coord_rect.lower_left()), ]; - self.draw_texture_with_vertex_data(device, - allocator, - &vertex_data, - &QUAD_INDICES, - texture, - color); + self.draw_texture_with_vertex_data( + device, + allocator, + &vertex_data, + &QUAD_INDICES, + texture, + color, + ); } pub fn measure_text(&self, string: &str) -> i32 { @@ -302,32 +371,38 @@ impl UIPresenter where D: Device { SEGMENT_SIZE * segment_count as i32 + (segment_count - 1) as i32 } - pub fn draw_solid_rounded_rect(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - rect: RectI, - color: ColorU) { + pub fn draw_solid_rounded_rect( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + 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, allocator, 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 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()), @@ -339,19 +414,23 @@ impl UIPresenter where D: Device { 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, - allocator, - &vertex_data, - &index_data[0..18], - color, - true); + self.draw_solid_rects_with_vertex_data( + device, + allocator, + &vertex_data, + &index_data[0..18], + color, + true, + ); } - pub fn draw_rounded_rect_outline(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - rect: RectI, - color: ColorU) { + pub fn draw_rounded_rect_outline( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + 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, allocator, color, corner_texture, &corner_rects); @@ -368,76 +447,109 @@ impl UIPresenter where D: Device { ]; let index_data = &OUTLINE_RECT_LINE_INDICES; - self.draw_solid_rects_with_vertex_data(device, - allocator, - &vertex_data, - index_data, - color, - false); + self.draw_solid_rects_with_vertex_data( + device, + allocator, + &vertex_data, + index_data, + color, + false, + ); } // TODO(pcwalton): `LineSegment2I`. - fn draw_line(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - from: Vector2I, - to: Vector2I, - color: ColorU) { + fn draw_line( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + from: Vector2I, + to: Vector2I, + color: ColorU, + ) { let vertex_data = vec![DebugSolidVertex::new(from), DebugSolidVertex::new(to)]; - self.draw_solid_rects_with_vertex_data(device, - allocator, - &vertex_data, - &[0, 1], - color, - false); - + self.draw_solid_rects_with_vertex_data( + device, + allocator, + &vertex_data, + &[0, 1], + color, + false, + ); } - fn draw_rounded_rect_corners(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - color: ColorU, - texture: &D::Texture, - corner_rects: &CornerRects) { + fn draw_rounded_rect_corners( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + 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.origin(), tex_coord_rect.origin()), + corner_rects.upper_left.upper_right(), + tex_coord_rect.upper_right(), + ), DebugTextureVertex::new( - corner_rects.upper_left.upper_right(), tex_coord_rect.upper_right()), + corner_rects.upper_left.lower_right(), + tex_coord_rect.lower_right(), + ), DebugTextureVertex::new( - corner_rects.upper_left.lower_right(), tex_coord_rect.lower_right()), + corner_rects.upper_left.lower_left(), + tex_coord_rect.lower_left(), + ), DebugTextureVertex::new( - corner_rects.upper_left.lower_left(), tex_coord_rect.lower_left()), - + corner_rects.upper_right.origin(), + tex_coord_rect.lower_left(), + ), DebugTextureVertex::new( - corner_rects.upper_right.origin(), tex_coord_rect.lower_left()), + corner_rects.upper_right.upper_right(), + tex_coord_rect.origin(), + ), DebugTextureVertex::new( - corner_rects.upper_right.upper_right(), tex_coord_rect.origin()), + corner_rects.upper_right.lower_right(), + tex_coord_rect.upper_right(), + ), DebugTextureVertex::new( - corner_rects.upper_right.lower_right(), tex_coord_rect.upper_right()), + corner_rects.upper_right.lower_left(), + tex_coord_rect.lower_right(), + ), DebugTextureVertex::new( - corner_rects.upper_right.lower_left(), tex_coord_rect.lower_right()), - + corner_rects.lower_left.origin(), + tex_coord_rect.upper_right(), + ), DebugTextureVertex::new( - corner_rects.lower_left.origin(), tex_coord_rect.upper_right()), + corner_rects.lower_left.upper_right(), + tex_coord_rect.lower_right(), + ), DebugTextureVertex::new( - corner_rects.lower_left.upper_right(), tex_coord_rect.lower_right()), + corner_rects.lower_left.lower_right(), + tex_coord_rect.lower_left(), + ), DebugTextureVertex::new( - corner_rects.lower_left.lower_right(), tex_coord_rect.lower_left()), + corner_rects.lower_left.lower_left(), + tex_coord_rect.origin(), + ), DebugTextureVertex::new( - corner_rects.lower_left.lower_left(), tex_coord_rect.origin()), - + corner_rects.lower_right.origin(), + tex_coord_rect.lower_right(), + ), DebugTextureVertex::new( - corner_rects.lower_right.origin(), tex_coord_rect.lower_right()), + corner_rects.lower_right.upper_right(), + tex_coord_rect.lower_left(), + ), DebugTextureVertex::new( - corner_rects.lower_right.upper_right(), tex_coord_rect.lower_left()), + corner_rects.lower_right.lower_right(), + tex_coord_rect.origin(), + ), 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()), + corner_rects.lower_right.lower_left(), + tex_coord_rect.upper_right(), + ), ]; let mut index_data = Vec::with_capacity(24); @@ -446,99 +558,130 @@ impl UIPresenter where D: Device { 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, - allocator, - &vertex_data, - &index_data, - texture, - color); + self.draw_texture_with_vertex_data( + device, + allocator, + &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 } + if filled { + &self.corner_fill_texture + } else { + &self.corner_outline_texture + } } - fn draw_texture_with_vertex_data(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - vertex_data: &[DebugTextureVertex], - index_data: &[u32], - texture: &D::Texture, - color: ColorU) { + fn draw_texture_with_vertex_data( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + vertex_data: &[DebugTextureVertex], + index_data: &[u32], + texture: &D::Texture, + color: ColorU, + ) { let vertex_buffer_id = allocator.allocate_general_buffer::( device, vertex_data.len() as u64, - BufferTag("TextureVertexDebug")); - let index_buffer_id = - allocator.allocate_index_buffer::(device, - index_data.len() as u64, - BufferTag("TextureIndexDebug")); + BufferTag("TextureVertexDebug"), + ); + let index_buffer_id = allocator.allocate_index_buffer::( + device, + index_data.len() as u64, + BufferTag("TextureIndexDebug"), + ); { let vertex_buffer = allocator.get_general_buffer(vertex_buffer_id); let index_buffer = allocator.get_index_buffer(index_buffer_id); device.upload_to_buffer(&vertex_buffer, 0, vertex_data, BufferTarget::Vertex); device.upload_to_buffer(&index_buffer, 0, index_data, BufferTarget::Index); - let texture_vertex_array = DebugTextureVertexArray::new(device, - &self.texture_program, - vertex_buffer, - index_buffer); + let texture_vertex_array = DebugTextureVertexArray::new( + device, + &self.texture_program, + vertex_buffer, + index_buffer, + ); - device.draw_elements(index_data.len() as u32, &RenderState { - target: &RenderTarget::Default, - program: &self.texture_program.program, - vertex_array: &texture_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[(&self.texture_program.texture, &texture)], - images: &[], - storage_buffers: &[], - 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_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() + device.draw_elements( + index_data.len() as u32, + &RenderState { + target: &RenderTarget::Default, + program: &self.texture_program.program, + vertex_array: &texture_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[(&self.texture_program.texture, &texture)], + images: &[], + storage_buffers: &[], + 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_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() + }, }, - }); + ); } allocator.free_index_buffer(index_buffer_id); allocator.free_general_buffer(vertex_buffer_id); } - pub fn draw_button(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - origin: Vector2I, - texture: &D::Texture) -> bool { + pub fn draw_button( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + origin: Vector2I, + texture: &D::Texture, + ) -> bool { let button_rect = RectI::new(origin, vec2i(BUTTON_WIDTH, BUTTON_HEIGHT)); self.draw_solid_rounded_rect(device, allocator, button_rect, WINDOW_COLOR); self.draw_rounded_rect_outline(device, allocator, button_rect, OUTLINE_COLOR); - self.draw_texture(device, - allocator, - origin + vec2i(PADDING, PADDING), - texture, - BUTTON_ICON_COLOR); - self.event_queue.handle_mouse_down_in_rect(button_rect).is_some() + self.draw_texture( + device, + allocator, + 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, - allocator: &mut GPUMemoryAllocator, - mut origin: Vector2I, - segment_labels: &[&str], - mut value: u8) - -> u8 { - if let Some(new_value) = self.draw_segmented_control(device, - allocator, - origin, - Some(value), - segment_labels.len() as u8) { + pub fn draw_text_switch( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + mut origin: Vector2I, + segment_labels: &[&str], + mut value: u8, + ) -> u8 { + if let Some(new_value) = self.draw_segmented_control( + device, + allocator, + origin, + Some(value), + segment_labels.len() as u8, + ) { value = new_value; } @@ -546,30 +689,35 @@ impl UIPresenter where D: Device { 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, - allocator, - segment_label, - origin + vec2i(offset, 0), - segment_index as u8 == value); + self.draw_text( + device, + allocator, + 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, - allocator: &mut GPUMemoryAllocator, - mut origin: Vector2I, - segment_textures: &[&D::Texture], - mut value: Option) - -> Option { + pub fn draw_image_segmented_control( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + 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, - allocator, - origin, - value, - segment_textures.len() as u8) { + if let Some(segment_index) = self.draw_segmented_control( + device, + allocator, + origin, + value, + segment_textures.len() as u8, + ) { if let Some(ref mut value) = value { *value = segment_index; } @@ -592,13 +740,14 @@ impl UIPresenter where D: Device { clicked_segment } - fn draw_segmented_control(&mut self, - device: &D, - allocator: &mut GPUMemoryAllocator, - origin: Vector2I, - mut value: Option, - segment_count: u8) - -> Option { + fn draw_segmented_control( + &mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + 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)); @@ -617,10 +766,12 @@ impl UIPresenter where D: Device { 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, - allocator, - RectI::new(origin + vec2i(x_offset, 0), highlight_size), - TEXT_COLOR); + self.draw_solid_rounded_rect( + device, + allocator, + RectI::new(origin + vec2i(x_offset, 0), highlight_size), + TEXT_COLOR, + ); } let mut segment_origin = origin + vec2i(SEGMENT_SIZE + 1, 0); @@ -629,11 +780,13 @@ impl UIPresenter where D: Device { match value { Some(value) if value == prev_segment_index || value == next_segment_index => {} _ => { - self.draw_line(device, - allocator, - segment_origin, - segment_origin + vec2i(0, BUTTON_HEIGHT), - TEXT_COLOR); + self.draw_line( + device, + allocator, + segment_origin, + segment_origin + vec2i(0, BUTTON_HEIGHT), + TEXT_COLOR, + ); } } segment_origin += vec2i(SEGMENT_SIZE + 1, 0); @@ -642,11 +795,13 @@ impl UIPresenter where D: Device { clicked_segment } - pub fn draw_tooltip(&self, - device: &D, - allocator: &mut GPUMemoryAllocator, - string: &str, - rect: RectI) { + pub fn draw_tooltip( + &self, + device: &D, + allocator: &mut GPUMemoryAllocator, + string: &str, + rect: RectI, + ) { if !rect.to_f32().contains_point(self.mouse_position) { return; } @@ -655,19 +810,26 @@ impl UIPresenter where D: Device { 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, - allocator, - RectI::new(origin, window_size), - WINDOW_COLOR); - self.draw_text(device, - allocator, - string, - origin + vec2i(PADDING, PADDING + FONT_ASCENT), - false); + self.draw_solid_rounded_rect( + device, + allocator, + RectI::new(origin, window_size), + WINDOW_COLOR, + ); + self.draw_text( + device, + allocator, + string, + origin + vec2i(PADDING, PADDING + FONT_ASCENT), + false, + ); } } -struct DebugTextureProgram where D: Device { +struct DebugTextureProgram +where + D: Device, +{ program: D::Program, framebuffer_size_uniform: D::Uniform, texture_size_uniform: D::Uniform, @@ -675,7 +837,10 @@ struct DebugTextureProgram where D: Device { texture: D::TextureParameter, } -impl DebugTextureProgram where D: Device { +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"); @@ -692,90 +857,129 @@ impl DebugTextureProgram where D: Device { } } -struct DebugTextureVertexArray where D: Device { +struct DebugTextureVertexArray +where + D: Device, +{ vertex_array: D::VertexArray, } -impl DebugTextureVertexArray where D: Device { - fn new(device: &D, - debug_texture_program: &DebugTextureProgram, - vertex_buffer: &D::Buffer, - index_buffer: &D::Buffer) - -> DebugTextureVertexArray { +impl DebugTextureVertexArray +where + D: Device, +{ + fn new( + device: &D, + debug_texture_program: &DebugTextureProgram, + vertex_buffer: &D::Buffer, + index_buffer: &D::Buffer, + ) -> DebugTextureVertexArray { 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(); + 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, - }); + 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 } } } -struct DebugSolidVertexArray where D: Device { +struct DebugSolidVertexArray +where + D: Device, +{ vertex_array: D::VertexArray, } -impl DebugSolidVertexArray where D: Device { - fn new(device: &D, - debug_solid_program: &DebugSolidProgram, - vertex_buffer: &D::Buffer, - index_buffer: &D::Buffer) - -> DebugSolidVertexArray { +impl DebugSolidVertexArray +where + D: Device, +{ + fn new( + device: &D, + debug_solid_program: &DebugSolidProgram, + vertex_buffer: &D::Buffer, + index_buffer: &D::Buffer, + ) -> DebugSolidVertexArray { let vertex_array = device.create_vertex_array(); - let position_attr = - device.get_vertex_attr(&debug_solid_program.program, "Position").unwrap(); + 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, - }); + 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 } } } -struct DebugSolidProgram where D: Device { +struct DebugSolidProgram +where + D: Device, +{ program: D::Program, framebuffer_size_uniform: D::Uniform, color_uniform: D::Uniform, } -impl DebugSolidProgram where D: Device { +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 } + DebugSolidProgram { + program, + framebuffer_size_uniform, + color_uniform, + } } } @@ -810,7 +1014,10 @@ struct DebugSolidVertex { impl DebugSolidVertex { fn new(position: Vector2I) -> DebugSolidVertex { - DebugSolidVertex { position_x: position.x() as i16, position_y: position.y() as i16 } + DebugSolidVertex { + position_x: position.x() as i16, + position_y: position.y() as i16, + } } } @@ -822,19 +1029,27 @@ struct CornerRects { } impl CornerRects { - fn new(device: &D, rect: RectI, texture: &D::Texture) -> CornerRects where D: Device { + 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_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), + 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); + 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)) } @@ -879,8 +1094,9 @@ impl UIEventQueue { 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) => { + UIEvent::MouseDown(position) | UIEvent::MouseDragged(position) + if rect.contains_point(position.absolute) => + { result = Some(position.absolute - rect.origin()); } event => remaining_events.push(event), diff --git a/utils/area-lut/src/main.rs b/utils/area-lut/src/main.rs index 09110b3d..5d64f586 100644 --- a/utils/area-lut/src/main.rs +++ b/utils/area-lut/src/main.rs @@ -69,17 +69,20 @@ fn main() { .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)); + .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]) + return Rgba([255, 255, 255, 255]); } if u == WIDTH - 1 { - return Rgba([0, 0, 0, 0]) + return Rgba([0, 0, 0, 0]); } let y = ((u as f32) - (WIDTH / 2) as f32) / 16.0; diff --git a/utils/convert/Cargo.toml b/utils/convert/Cargo.toml index 4f88c522..ddeb99c7 100644 --- a/utils/convert/Cargo.toml +++ b/utils/convert/Cargo.toml @@ -9,4 +9,4 @@ edition = "2018" [dependencies] pathfinder_export = { path = "../../export" } pathfinder_svg = { path = "../../svg" } -usvg = "0.9" +usvg = "0.10" diff --git a/utils/convert/src/main.rs b/utils/convert/src/main.rs index e45432f9..80ceb62f 100644 --- a/utils/convert/src/main.rs +++ b/utils/convert/src/main.rs @@ -1,10 +1,10 @@ -use std::fs::File; -use std::io::{Read, BufWriter}; -use std::error::Error; -use std::path::PathBuf; -use pathfinder_svg::SVGScene; use pathfinder_export::{Export, FileFormat}; -use usvg::{Tree, Options}; +use pathfinder_svg::SVGScene; +use std::error::Error; +use std::fs::File; +use std::io::{BufWriter, Read}; +use std::path::PathBuf; +use usvg::{Options, Tree}; fn main() -> Result<(), Box> { let mut args = std::env::args_os().skip(1); @@ -20,7 +20,7 @@ fn main() -> Result<(), Box> { 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()) + _ => return Err("output filename must have .ps or .pdf extension".into()), }; scene.export(&mut writer, format).unwrap(); Ok(()) diff --git a/utils/gamma-lut/src/gamma_lut.rs b/utils/gamma-lut/src/gamma_lut.rs index eba7f810..2bae6b10 100644 --- a/utils/gamma-lut/src/gamma_lut.rs +++ b/utils/gamma-lut/src/gamma_lut.rs @@ -62,7 +62,7 @@ impl LuminanceColorSpace { if luma <= 0.0031308 { luma * 12.92 } else { - 1.055 * luma.powf(1./2.4) - 0.055 + 1.055 * luma.powf(1. / 2.4) - 0.055 } } } @@ -70,7 +70,7 @@ impl LuminanceColorSpace { } //TODO: tests -fn round_to_u8(x : f32) -> u8 { +fn round_to_u8(x: f32) -> u8 { let v = (x + 0.5).floor() as i32; assert!(0 <= v && v < 0x100); v as u8 @@ -134,12 +134,7 @@ impl ColorLut for ColorU { // 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, - ) + 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. @@ -176,10 +171,13 @@ fn apply_contrast(srca: f32, contrast: f32) -> f32 { // 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) { - +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 @@ -195,7 +193,7 @@ pub fn build_gamma_correcting_lut(table: &mut [u8; 256], src: u8, contrast: f32, // 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; + 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); @@ -205,7 +203,7 @@ pub fn build_gamma_correcting_lut(table: &mut [u8; 256], src: u8, contrast: f32, } } else { // Avoid slow int to float conversion. - let mut ii : f32 = 0.0; + 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. @@ -247,11 +245,13 @@ impl GammaLut { 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); + build_gamma_correcting_lut( + entry, + luminance, + contrast, + paint_color_space, + device_color_space, + ); } } @@ -280,7 +280,11 @@ impl GammaLut { 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]); + 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; @@ -301,7 +305,6 @@ impl GammaLut { pixel[3] = alpha; } } - } // end impl GammaLut #[cfg(test)] @@ -309,16 +312,19 @@ mod tests { use super::*; fn over(dst: u32, src: u32, alpha: u32) -> u32 { - (src * alpha + dst * (255 - alpha))/255 + (src * alpha + dst * (255 - alpha)) / 255 } fn overf(dst: f32, src: f32, alpha: f32) -> f32 { - ((src * alpha + dst * (255. - alpha))/255.) as f32 + ((src * alpha + dst * (255. - alpha)) / 255.) as f32 } - fn absdiff(a: u32, b: u32) -> u32 { - if a < b { b - a } else { a - b } + if a < b { + b - a + } else { + a - b + } } #[test] @@ -326,7 +332,7 @@ mod tests { let mut table = [0u8; 256]; let g = 2.0; let space = LuminanceColorSpace::Gamma(g); - let mut src : u32 = 131; + 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; @@ -338,7 +344,8 @@ mod tests { 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 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); @@ -347,7 +354,6 @@ mod tests { //println!("{} {} max {}", src, dst, max_diff); assert!(max_diff <= 33); dst += 1; - } src += 1; } diff --git a/utils/gamma-lut/src/main.rs b/utils/gamma-lut/src/main.rs index d2db1069..fd4e058f 100644 --- a/utils/gamma-lut/src/main.rs +++ b/utils/gamma-lut/src/main.rs @@ -42,9 +42,12 @@ pub fn main() { .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)); + .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); diff --git a/utils/svg-to-skia/Cargo.toml b/utils/svg-to-skia/Cargo.toml index 06af2c75..9a23db0a 100644 --- a/utils/svg-to-skia/Cargo.toml +++ b/utils/svg-to-skia/Cargo.toml @@ -5,4 +5,4 @@ authors = ["Patrick Walton "] edition = "2018" [dependencies] -usvg = "0.9" +usvg = "0.10" diff --git a/utils/svg-to-skia/src/main.rs b/utils/svg-to-skia/src/main.rs index 8a971421..fc1d570e 100644 --- a/utils/svg-to-skia/src/main.rs +++ b/utils/svg-to-skia/src/main.rs @@ -49,9 +49,18 @@ fn process_node(node: &Node) { 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::CurveTo { + x1, + y1, + x2, + y2, + x, + y, + } => { + println!( + " path.cubicTo({}, {}, {}, {}, {}, {});", + x1, y1, x2, y2, x, y + ); } PathSegment::ClosePath => println!(" path.close();"), } @@ -78,10 +87,12 @@ fn process_node(node: &Node) { 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)); + 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/web_canvas/src/lib.rs b/web_canvas/src/lib.rs index e2b908a6..184ba2fa 100644 --- a/web_canvas/src/lib.rs +++ b/web_canvas/src/lib.rs @@ -23,8 +23,8 @@ use pathfinder_resources::embedded::EmbeddedResourceLoader; use pathfinder_webgl::WebGlDevice; use std::str::FromStr; use std::sync::Arc; -use wasm_bindgen::JsCast; use wasm_bindgen::prelude::*; +use wasm_bindgen::JsCast; use web_sys::{self, HtmlCanvasElement, WebGl2RenderingContext}; #[wasm_bindgen] @@ -45,11 +45,12 @@ struct WebCanvasState { #[wasm_bindgen(js_name = "createContext")] pub fn create_context(html_canvas: HtmlCanvasElement) -> PFCanvasRenderingContext2D { - let context = html_canvas.get_context("webgl2") - .unwrap() - .unwrap() - .dyn_into::() - .unwrap(); + let context = html_canvas + .get_context("webgl2") + .unwrap() + .unwrap() + .dyn_into::() + .unwrap(); // Get the real size of the window, taking HiDPI into account. let framebuffer_size = vec2i(html_canvas.width() as i32, html_canvas.height() as i32); @@ -89,15 +90,21 @@ impl PFCanvasRenderingContext2D { #[wasm_bindgen(js_name = "pfFlush")] pub fn pf_flush(&mut self) { // Update framebuffer size. - let framebuffer_size = vec2i(self.html_canvas.width() as i32, - self.html_canvas.height() as i32); + let framebuffer_size = vec2i( + self.html_canvas.width() as i32, + self.html_canvas.height() as i32, + ); self.renderer.options_mut().dest = DestFramebuffer::full_window(framebuffer_size); self.renderer.options_mut().background_color = None; self.renderer.dest_framebuffer_size_changed(); // TODO(pcwalton): This is inefficient! let mut scene = (*self.context.canvas_mut().scene()).clone(); - scene.build_and_render(&mut self.renderer, BuildOptions::default(), SequentialExecutor); + scene.build_and_render( + &mut self.renderer, + BuildOptions::default(), + SequentialExecutor, + ); self.context.canvas_mut().set_size(framebuffer_size); } @@ -116,17 +123,20 @@ impl PFCanvasRenderingContext2D { #[wasm_bindgen(js_name = "clearRect")] pub fn clear_rect(&mut self, x: f32, y: f32, width: f32, height: f32) { - self.context.clear_rect(RectF::new(vec2f(x, y), vec2f(width, height))); + self.context + .clear_rect(RectF::new(vec2f(x, y), vec2f(width, height))); } #[wasm_bindgen(js_name = "fillRect")] pub fn fill_rect(&mut self, x: f32, y: f32, width: f32, height: f32) { - self.context.fill_rect(RectF::new(vec2f(x, y), vec2f(width, height))); + self.context + .fill_rect(RectF::new(vec2f(x, y), vec2f(width, height))); } #[wasm_bindgen(js_name = "strokeRect")] pub fn stroke_rect(&mut self, x: f32, y: f32, width: f32, height: f32) { - self.context.stroke_rect(RectF::new(vec2f(x, y), vec2f(width, height))); + self.context + .stroke_rect(RectF::new(vec2f(x, y), vec2f(width, height))); } // TODO(pcwalton): Drawing text @@ -219,12 +229,14 @@ impl PFCanvasRenderingContext2D { #[wasm_bindgen(js_name = "bezierCurveTo")] pub fn bezier_curve_to(&mut self, cp1x: f32, cp1y: f32, cp2x: f32, cp2y: f32, x: f32, y: f32) { - self.default_path.bezier_curve_to(vec2f(cp1x, cp1y), vec2f(cp2x, cp2y), vec2f(x, y)) + self.default_path + .bezier_curve_to(vec2f(cp1x, cp1y), vec2f(cp2x, cp2y), vec2f(x, y)) } #[wasm_bindgen(js_name = "quadraticCurveTo")] pub fn quadratic_curve_to(&mut self, cpx: f32, cpy: f32, x: f32, y: f32) { - self.default_path.quadratic_curve_to(vec2f(cpx, cpy), vec2f(x, y)) + self.default_path + .quadratic_curve_to(vec2f(cpx, cpy), vec2f(x, y)) } #[wasm_bindgen(js_name = "closePath")] @@ -260,9 +272,11 @@ fn parse_fill_or_stroke_style(string: &str) -> Option { Err(_) => return None, Ok(css_color) => css_color, }; - let color = ColorU::new(css_color.r, - css_color.g, - css_color.b, - (css_color.a * 255.0).round() as u8); + let color = ColorU::new( + css_color.r, + css_color.g, + css_color.b, + (css_color.a * 255.0).round() as u8, + ); Some(FillStyle::Color(color)) } diff --git a/webgl/src/lib.rs b/webgl/src/lib.rs index b828bebd..3cee8272 100644 --- a/webgl/src/lib.rs +++ b/webgl/src/lib.rs @@ -13,7 +13,7 @@ #[macro_use] extern crate log; -use js_sys::{Uint8Array, Uint16Array, Float32Array, Object}; +use js_sys::{Float32Array, Object, Uint16Array, Uint8Array}; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::vector::Vector2I; use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode, ClearOps}; @@ -186,12 +186,16 @@ impl WebGlDevice { self.clear(&render_state.options.clear_ops); } - self.context.use_program(Some(&render_state.program.gl_program)); - self.context.bind_vertex_array(Some(&render_state.vertex_array.gl_vertex_array)); + self.context + .use_program(Some(&render_state.program.gl_program)); + self.context + .bind_vertex_array(Some(&render_state.vertex_array.gl_vertex_array)); - self.bind_textures_and_images(&render_state.program, - &render_state.textures, - &render_state.images); + self.bind_textures_and_images( + &render_state.program, + &render_state.textures, + &render_state.images, + ); for (uniform, data) in render_state.uniforms { self.set_uniform(uniform, data); @@ -200,17 +204,19 @@ impl WebGlDevice { } fn bind_textures_and_images( - &self, - program: &WebGlProgram, - texture_bindings: &[TextureBinding], - _: &[ImageBinding<(), WebGlTexture>]) { + &self, + program: &WebGlProgram, + texture_bindings: &[TextureBinding], + _: &[ImageBinding<(), WebGlTexture>], + ) { for &(texture_parameter, texture) in texture_bindings { self.bind_texture(texture, texture_parameter.texture_unit); } let parameters = program.parameters.borrow(); for (texture_unit, uniform) in parameters.textures.iter().enumerate() { - self.context.uniform1i(uniform.location.as_ref(), texture_unit as i32); + self.context + .uniform1i(uniform.location.as_ref(), texture_unit as i32); self.ck(); } } @@ -486,9 +492,7 @@ impl Device for WebGlDevice { size: Vector2I, data_ref: TextureDataRef, ) -> WebGlTexture { - let data = unsafe { - check_and_extract_data(data_ref, size, format) - }; + let data = unsafe { check_and_extract_data(data_ref, size, format) }; let texture = self.context.create_texture().unwrap(); let texture = WebGlTexture { @@ -568,7 +572,10 @@ impl Device for WebGlDevice { .create_program() .expect("unable to create program object"); match shaders { - ProgramKind::Raster { ref vertex, ref fragment } => { + ProgramKind::Raster { + ref vertex, + ref fragment, + } => { self.context.attach_shader(&gl_program, &vertex.gl_shader); self.context.attach_shader(&gl_program, &fragment.gl_shader); } @@ -622,7 +629,9 @@ impl Device for WebGlDevice { fn get_uniform(&self, program: &WebGlProgram, name: &str) -> WebGlUniform { let name = format!("u{}", name); - let location = self.context.get_uniform_location(&program.gl_program, &name); + let location = self + .context + .get_uniform_location(&program.gl_program, &name); self.ck(); WebGlUniform { location: location } } @@ -638,7 +647,10 @@ impl Device for WebGlDevice { index } }; - WebGlTextureParameter { uniform, texture_unit: index as u32 } + WebGlTextureParameter { + uniform, + texture_unit: index as u32, + } } fn get_image_parameter(&self, _: &WebGlProgram, _: &str) { @@ -744,12 +756,7 @@ impl Device for WebGlDevice { } } - fn allocate_buffer( - &self, - buffer: &WebGlBuffer, - data: BufferData, - target: BufferTarget, - ) { + fn allocate_buffer(&self, buffer: &WebGlBuffer, data: BufferData, target: BufferTarget) { let target = match target { BufferTarget::Vertex => WebGl::ARRAY_BUFFER, BufferTarget::Index => WebGl::ELEMENT_ARRAY_BUFFER, @@ -770,16 +777,22 @@ impl Device for WebGlDevice { } } - fn upload_to_buffer(&self, - buffer: &Self::Buffer, - position: usize, - data: &[T], - target: BufferTarget) { + fn upload_to_buffer( + &self, + buffer: &Self::Buffer, + position: usize, + data: &[T], + target: BufferTarget, + ) { let target = target.to_gl_target(); - self.context.bind_buffer(target, Some(&buffer.buffer)); self.ck(); - self.context.buffer_sub_data_with_i32_and_u8_array(target, - position as i32, - slice_to_u8(data)); self.ck(); + self.context.bind_buffer(target, Some(&buffer.buffer)); + self.ck(); + self.context.buffer_sub_data_with_i32_and_u8_array( + target, + position as i32, + slice_to_u8(data), + ); + self.ck(); } #[inline] @@ -794,44 +807,46 @@ impl Device for WebGlDevice { fn set_texture_sampling_mode(&self, texture: &Self::Texture, flags: TextureSamplingFlags) { self.bind_texture(texture, 0); - self.context - .tex_parameteri(WebGl::TEXTURE_2D, - WebGl::TEXTURE_MIN_FILTER, - if flags.contains(TextureSamplingFlags::NEAREST_MIN) { - WebGl::NEAREST as i32 - } else { - WebGl::LINEAR as i32 - }); - self.context - .tex_parameteri(WebGl::TEXTURE_2D, - WebGl::TEXTURE_MAG_FILTER, - if flags.contains(TextureSamplingFlags::NEAREST_MAG) { - WebGl::NEAREST as i32 - } else { - WebGl::LINEAR as i32 - }); - self.context - .tex_parameteri(WebGl::TEXTURE_2D, - WebGl::TEXTURE_WRAP_S, - if flags.contains(TextureSamplingFlags::REPEAT_U) { - WebGl::REPEAT as i32 - } else { - WebGl::CLAMP_TO_EDGE as i32 - }); - self.context - .tex_parameteri(WebGl::TEXTURE_2D, - WebGl::TEXTURE_WRAP_T, - if flags.contains(TextureSamplingFlags::REPEAT_V) { - WebGl::REPEAT as i32 - } else { - WebGl::CLAMP_TO_EDGE as i32 - }); + self.context.tex_parameteri( + WebGl::TEXTURE_2D, + WebGl::TEXTURE_MIN_FILTER, + if flags.contains(TextureSamplingFlags::NEAREST_MIN) { + WebGl::NEAREST as i32 + } else { + WebGl::LINEAR as i32 + }, + ); + self.context.tex_parameteri( + WebGl::TEXTURE_2D, + WebGl::TEXTURE_MAG_FILTER, + if flags.contains(TextureSamplingFlags::NEAREST_MAG) { + WebGl::NEAREST as i32 + } else { + WebGl::LINEAR as i32 + }, + ); + self.context.tex_parameteri( + WebGl::TEXTURE_2D, + WebGl::TEXTURE_WRAP_S, + if flags.contains(TextureSamplingFlags::REPEAT_U) { + WebGl::REPEAT as i32 + } else { + WebGl::CLAMP_TO_EDGE as i32 + }, + ); + self.context.tex_parameteri( + WebGl::TEXTURE_2D, + WebGl::TEXTURE_WRAP_T, + if flags.contains(TextureSamplingFlags::REPEAT_V) { + WebGl::REPEAT as i32 + } else { + WebGl::CLAMP_TO_EDGE as i32 + }, + ); } fn upload_to_texture(&self, texture: &WebGlTexture, rect: RectI, data_ref: TextureDataRef) { - let data = unsafe { - check_and_extract_data(data_ref, rect.size(), texture.format) - }; + let data = unsafe { check_and_extract_data(data_ref, rect.size(), texture.format) }; assert!(rect.size().x() >= 0); assert!(rect.size().y() >= 0); assert!(rect.max_x() <= texture.size.x());