klyff 0.1.2

Text rendering library for games with MSDF support
Documentation
/// Size of [`crate::TextureAtlas`].
///
/// The atlas can start out as or grow into a texture array. An atlas with layer count of 2 or
/// above have the maximum texture width & height that the device allows, while an atlas with only
/// one layer can have arbitrary size.
///
/// Growing: in each iteration, single layer texture doubles in size; single layer texture with max
/// width and height and multi-layer texture increases layer count by 1.
pub enum AtlasSize {
    /// Only one layer with arbitrary size. Recommened to use power of two if texture can grow.
    SingleLayer { width: u32, height: u32 },
    /// Each layer uses the maximum texture size the device allows.
    MaxSize { layer_count: u32 },
}

pub(super) fn grow_size(size: wgpu::Extent3d, max_size: wgpu::Extent3d) -> wgpu::Extent3d {
    if size.depth_or_array_layers > 1
        || (size.width == max_size.width && size.height == max_size.height)
    {
        wgpu::Extent3d {
            depth_or_array_layers: (size.depth_or_array_layers + 1)
                .min(max_size.depth_or_array_layers),
            ..max_size
        }
    } else {
        let width = 1 << (f32::log2(size.width as f32).round() as u64 + 1);
        let height = 1 << (f32::log2(size.height as f32).round() as u64 + 1);
        wgpu::Extent3d {
            width: width.min(max_size.width),
            height: height.min(max_size.height),
            depth_or_array_layers: 1,
        }
    }
}

#[cfg(test)]
mod test {
    use super::grow_size;

    #[test]
    fn grow_width_and_height() {
        assert_eq!(
            grow_size(
                wgpu::Extent3d {
                    width: 512,
                    height: 512,
                    depth_or_array_layers: 1
                },
                wgpu::Extent3d {
                    width: 2048,
                    height: 2048,
                    depth_or_array_layers: 128
                }
            ),
            wgpu::Extent3d {
                width: 1024,
                height: 1024,
                depth_or_array_layers: 1
            }
        );

        assert_eq!(
            grow_size(
                wgpu::Extent3d {
                    width: 450,
                    height: 450,
                    depth_or_array_layers: 1
                },
                wgpu::Extent3d {
                    width: 2048,
                    height: 2048,
                    depth_or_array_layers: 128
                }
            ),
            wgpu::Extent3d {
                width: 1024,
                height: 1024,
                depth_or_array_layers: 1
            }
        );

        assert_eq!(
            grow_size(
                wgpu::Extent3d {
                    width: 600,
                    height: 600,
                    depth_or_array_layers: 1
                },
                wgpu::Extent3d {
                    width: 2048,
                    height: 2048,
                    depth_or_array_layers: 128
                }
            ),
            wgpu::Extent3d {
                width: 1024,
                height: 1024,
                depth_or_array_layers: 1
            }
        );
    }

    #[test]
    fn grow_to_two_layers() {
        assert_eq!(
            grow_size(
                wgpu::Extent3d {
                    width: 2048,
                    height: 2048,
                    depth_or_array_layers: 1
                },
                wgpu::Extent3d {
                    width: 2048,
                    height: 2048,
                    depth_or_array_layers: 128
                }
            ),
            wgpu::Extent3d {
                width: 2048,
                height: 2048,
                depth_or_array_layers: 2
            }
        );
    }

    #[test]
    fn clamped_to_max_size() {
        assert_eq!(
            grow_size(
                wgpu::Extent3d {
                    width: 1040,
                    height: 1040,
                    depth_or_array_layers: 1
                },
                wgpu::Extent3d {
                    width: 2048,
                    height: 2048,
                    depth_or_array_layers: 128
                }
            ),
            wgpu::Extent3d {
                width: 2048,
                height: 2048,
                depth_or_array_layers: 1
            }
        );

        assert_eq!(
            grow_size(
                wgpu::Extent3d {
                    width: 2000,
                    height: 2000,
                    depth_or_array_layers: 1
                },
                wgpu::Extent3d {
                    width: 2048,
                    height: 2048,
                    depth_or_array_layers: 128
                }
            ),
            wgpu::Extent3d {
                width: 2048,
                height: 2048,
                depth_or_array_layers: 1
            }
        );
    }

    #[test]
    fn clamped_to_max_layer() {
        assert_eq!(
            grow_size(
                wgpu::Extent3d {
                    width: 2048,
                    height: 2048,
                    depth_or_array_layers: 128
                },
                wgpu::Extent3d {
                    width: 2048,
                    height: 2048,
                    depth_or_array_layers: 128
                },
            ),
            wgpu::Extent3d {
                width: 2048,
                height: 2048,
                depth_or_array_layers: 128
            },
        );
    }
}