| // Copyright 2022 the Vello Authors | 
 | // SPDX-License-Identifier: Apache-2.0 OR MIT | 
 |  | 
 | //! Create a lookup table of half-plane sample masks. | 
 |  | 
 | // Width is number of discrete translations | 
 | const MASK_WIDTH: usize = 32; | 
 | // Height is the number of discrete slopes | 
 | const MASK_HEIGHT: usize = 32; | 
 |  | 
 | const PATTERN: [u8; 8] = [0, 5, 3, 7, 1, 4, 6, 2]; | 
 |  | 
 | fn one_mask(slope: f64, mut translation: f64, is_pos: bool) -> u8 { | 
 |     if is_pos { | 
 |         translation = 1. - translation; | 
 |     } | 
 |     let mut result = 0; | 
 |     for (i, item) in PATTERN.iter().enumerate() { | 
 |         let mut y = (i as f64 + 0.5) * 0.125; | 
 |         let x = (*item as f64 + 0.5) * 0.125; | 
 |         if !is_pos { | 
 |             y = 1. - y; | 
 |         } | 
 |         if (x - (1.0 - translation)) * (1. - slope) - (y - translation) * slope >= 0. { | 
 |             result |= 1 << i; | 
 |         } | 
 |     } | 
 |     result | 
 | } | 
 |  | 
 | /// Make a lookup table of half-plane masks. | 
 | /// | 
 | /// The table is organized into two blocks each with `MASK_HEIGHT/2` slopes. | 
 | /// The first block is negative slopes (x decreases as y increases), | 
 | /// the second as positive. | 
 | pub fn make_mask_lut() -> Vec<u8> { | 
 |     (0..MASK_WIDTH * MASK_HEIGHT) | 
 |         .map(|i| { | 
 |             const HALF_HEIGHT: usize = MASK_HEIGHT / 2; | 
 |             let u = i % MASK_WIDTH; | 
 |             let v = i / MASK_WIDTH; | 
 |             let is_pos = v >= HALF_HEIGHT; | 
 |             let y = ((v % HALF_HEIGHT) as f64 + 0.5) * (1.0 / HALF_HEIGHT as f64); | 
 |             let x = (u as f64 + 0.5) * (1.0 / MASK_WIDTH as f64); | 
 |             one_mask(y, x, is_pos) | 
 |         }) | 
 |         .collect() | 
 | } | 
 |  | 
 | // Width is number of discrete translations | 
 | const MASK16_WIDTH: usize = 64; | 
 | // Height is the number of discrete slopes | 
 | const MASK16_HEIGHT: usize = 64; | 
 |  | 
 | // This is based on the [D3D11 standard sample pattern]. | 
 | // | 
 | // [D3D11 standard sample pattern]: https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_standard_multisample_quality_levels | 
 | const PATTERN_16: [u8; 16] = [1, 8, 4, 11, 15, 7, 3, 12, 0, 9, 5, 13, 2, 10, 6, 14]; | 
 |  | 
 | fn one_mask_16(slope: f64, mut translation: f64, is_pos: bool) -> u16 { | 
 |     if is_pos { | 
 |         translation = 1. - translation; | 
 |     } | 
 |     let mut result = 0; | 
 |     for (i, item) in PATTERN_16.iter().enumerate() { | 
 |         let mut y = (i as f64 + 0.5) * 0.0625; | 
 |         let x = (*item as f64 + 0.5) * 0.0625; | 
 |         if !is_pos { | 
 |             y = 1. - y; | 
 |         } | 
 |         if (x - (1.0 - translation)) * (1. - slope) - (y - translation) * slope >= 0. { | 
 |             result |= 1 << i; | 
 |         } | 
 |     } | 
 |     result | 
 | } | 
 |  | 
 | /// Make a lookup table of half-plane masks. | 
 | /// | 
 | /// The table is organized into two blocks each with `MASK16_HEIGHT/2` slopes. | 
 | /// The first block is negative slopes (x decreases as y increases), | 
 | /// the second as positive. | 
 | pub fn make_mask_lut_16() -> Vec<u8> { | 
 |     let v16 = (0..MASK16_WIDTH * MASK16_HEIGHT) | 
 |         .map(|i| { | 
 |             const HALF_HEIGHT: usize = MASK16_HEIGHT / 2; | 
 |             let u = i % MASK16_WIDTH; | 
 |             let v = i / MASK16_WIDTH; | 
 |             let is_pos = v >= HALF_HEIGHT; | 
 |             let y = ((v % HALF_HEIGHT) as f64 + 0.5) * (1.0 / HALF_HEIGHT as f64); | 
 |             let x = (u as f64 + 0.5) * (1.0 / MASK16_WIDTH as f64); | 
 |             one_mask_16(y, x, is_pos) | 
 |         }) | 
 |         .collect::<Vec<_>>(); | 
 |     // This annoyingly makes another copy. We can avoid that by pushing two | 
 |     // bytes per iteration of the above loop. | 
 |     bytemuck::cast_slice(&v16).into() | 
 | } |