Introduce ColorMode for Atlas
		
	This commit is contained in:
		
					parent
					
						
							
								80e8465af6
							
						
					
				
			
			
				commit
				
					
						9f82af4f7d
					
				
			
		
					 3 changed files with 83 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -3,7 +3,7 @@ mod text_atlas;
 | 
			
		|||
mod text_render;
 | 
			
		||||
 | 
			
		||||
pub use error::{PrepareError, RenderError};
 | 
			
		||||
pub use text_atlas::TextAtlas;
 | 
			
		||||
pub use text_atlas::{ColorMode, TextAtlas};
 | 
			
		||||
use text_render::ContentType;
 | 
			
		||||
pub use text_render::TextRenderer;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,17 +15,17 @@ use wgpu::{
 | 
			
		|||
 | 
			
		||||
#[allow(dead_code)]
 | 
			
		||||
pub(crate) struct InnerAtlas {
 | 
			
		||||
    pub kind: Kind,
 | 
			
		||||
    pub texture: Texture,
 | 
			
		||||
    pub texture_view: TextureView,
 | 
			
		||||
    pub packer: BucketedAtlasAllocator,
 | 
			
		||||
    pub width: u32,
 | 
			
		||||
    pub height: u32,
 | 
			
		||||
    pub glyph_cache: LruCache<CacheKey, GlyphDetails>,
 | 
			
		||||
    pub num_atlas_channels: usize,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl InnerAtlas {
 | 
			
		||||
    fn new(device: &Device, _queue: &Queue, num_atlas_channels: usize) -> Self {
 | 
			
		||||
    fn new(device: &Device, _queue: &Queue, kind: Kind) -> Self {
 | 
			
		||||
        let max_texture_dimension_2d = device.limits().max_texture_dimension_2d;
 | 
			
		||||
        let width = max_texture_dimension_2d;
 | 
			
		||||
        let height = max_texture_dimension_2d;
 | 
			
		||||
| 
						 | 
				
			
			@ -43,11 +43,7 @@ impl InnerAtlas {
 | 
			
		|||
            mip_level_count: 1,
 | 
			
		||||
            sample_count: 1,
 | 
			
		||||
            dimension: TextureDimension::D2,
 | 
			
		||||
            format: match num_atlas_channels {
 | 
			
		||||
                1 => TextureFormat::R8Unorm,
 | 
			
		||||
                4 => TextureFormat::Rgba8UnormSrgb,
 | 
			
		||||
                _ => panic!("unexpected number of channels"),
 | 
			
		||||
            },
 | 
			
		||||
            format: kind.texture_format(),
 | 
			
		||||
            usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST,
 | 
			
		||||
            view_formats: &[],
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			@ -57,13 +53,13 @@ impl InnerAtlas {
 | 
			
		|||
        let glyph_cache = LruCache::unbounded();
 | 
			
		||||
 | 
			
		||||
        Self {
 | 
			
		||||
            kind,
 | 
			
		||||
            texture,
 | 
			
		||||
            texture_view,
 | 
			
		||||
            packer,
 | 
			
		||||
            width,
 | 
			
		||||
            height,
 | 
			
		||||
            glyph_cache,
 | 
			
		||||
            num_atlas_channels,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +78,61 @@ impl InnerAtlas {
 | 
			
		|||
                .deallocate(value.atlas_id.expect("cache corrupt"));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn num_channels(&self) -> usize {
 | 
			
		||||
        self.kind.num_channels()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
			
		||||
pub(crate) enum Kind {
 | 
			
		||||
    Mask,
 | 
			
		||||
    Color { srgb: bool },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Kind {
 | 
			
		||||
    fn num_channels(self) -> usize {
 | 
			
		||||
        match self {
 | 
			
		||||
            Kind::Mask => 1,
 | 
			
		||||
            Kind::Color { .. } => 4,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn texture_format(self) -> wgpu::TextureFormat {
 | 
			
		||||
        match self {
 | 
			
		||||
            Kind::Mask => TextureFormat::R8Unorm,
 | 
			
		||||
            Kind::Color { srgb } => {
 | 
			
		||||
                if srgb {
 | 
			
		||||
                    TextureFormat::Rgba8UnormSrgb
 | 
			
		||||
                } else {
 | 
			
		||||
                    TextureFormat::Rgba8Unorm
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The color mode of an [`Atlas`].
 | 
			
		||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
			
		||||
pub enum ColorMode {
 | 
			
		||||
    /// Accurate color management.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This mode will use a proper sRGB texture for colored glyphs. This will
 | 
			
		||||
    /// produce physically accurate color blending when rendering.
 | 
			
		||||
    Accurate,
 | 
			
		||||
 | 
			
		||||
    /// Web color management.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This mode reproduces the color management strategy used in the Web and
 | 
			
		||||
    /// implemented by browsers.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This entails storing glyphs colored using the sRGB color space in a
 | 
			
		||||
    /// linear RGB texture. Blending will not be physically accurate, but will
 | 
			
		||||
    /// produce the same results as most UI toolkits.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This mode should be used to render to a linear RGB texture containing
 | 
			
		||||
    /// sRGB colors.
 | 
			
		||||
    Web,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// An atlas containing a cache of rasterized glyphs that can be rendered.
 | 
			
		||||
| 
						 | 
				
			
			@ -103,8 +154,18 @@ pub struct TextAtlas {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
impl TextAtlas {
 | 
			
		||||
    /// Creates a new `TextAtlas`.
 | 
			
		||||
    /// Creates a new [`TextAtlas`].
 | 
			
		||||
    pub fn new(device: &Device, queue: &Queue, format: TextureFormat) -> Self {
 | 
			
		||||
        Self::with_color_mode(device, queue, format, ColorMode::Accurate)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Creates a new [`TextAtlas`] with the given [`ColorMode`].
 | 
			
		||||
    pub fn with_color_mode(
 | 
			
		||||
        device: &Device,
 | 
			
		||||
        queue: &Queue,
 | 
			
		||||
        format: TextureFormat,
 | 
			
		||||
        color_mode: ColorMode,
 | 
			
		||||
    ) -> Self {
 | 
			
		||||
        let sampler = device.create_sampler(&SamplerDescriptor {
 | 
			
		||||
            label: Some("glyphon sampler"),
 | 
			
		||||
            min_filter: FilterMode::Nearest,
 | 
			
		||||
| 
						 | 
				
			
			@ -215,8 +276,17 @@ impl TextAtlas {
 | 
			
		|||
            mapped_at_creation: false,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let color_atlas = InnerAtlas::new(device, queue, 4);
 | 
			
		||||
        let mask_atlas = InnerAtlas::new(device, queue, 1);
 | 
			
		||||
        let color_atlas = InnerAtlas::new(
 | 
			
		||||
            device,
 | 
			
		||||
            queue,
 | 
			
		||||
            Kind::Color {
 | 
			
		||||
                srgb: match color_mode {
 | 
			
		||||
                    ColorMode::Accurate => true,
 | 
			
		||||
                    ColorMode::Web => false,
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
        let mask_atlas = InnerAtlas::new(device, queue, Kind::Mask);
 | 
			
		||||
 | 
			
		||||
        let bind_group = Arc::new(device.create_bind_group(&BindGroupDescriptor {
 | 
			
		||||
            layout: &bind_group_layout,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ impl TextRenderer {
 | 
			
		|||
                            &image.data,
 | 
			
		||||
                            ImageDataLayout {
 | 
			
		||||
                                offset: 0,
 | 
			
		||||
                                bytes_per_row: Some(width as u32 * inner.num_atlas_channels as u32),
 | 
			
		||||
                                bytes_per_row: Some(width as u32 * inner.num_channels() as u32),
 | 
			
		||||
                                rows_per_image: None,
 | 
			
		||||
                            },
 | 
			
		||||
                            Extent3d {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue