From f7d731bcc2693e77c2ff9fb53ce544aa3351f1dc Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Tue, 24 Oct 2023 22:28:18 +0200 Subject: [PATCH] dynamically allocate atlas size --- src/atlas.rs | 91 +++++++++------ src/glyphs.rs | 88 +++++---------- src/lib.rs | 294 ++++++++++++------------------------------------ src/shader.wgsl | 28 +++-- tests/tests.rs | 21 +--- 5 files changed, 180 insertions(+), 342 deletions(-) diff --git a/src/atlas.rs b/src/atlas.rs index f466a60..ae94089 100644 --- a/src/atlas.rs +++ b/src/atlas.rs @@ -13,6 +13,9 @@ pub enum AtlasContent { } pub struct Atlas { + pub(crate) max_seen: u32, + width: u32, + height: u32, packer: Packer, new_data: Vec, pub atlas_texture: wgpu::Texture, @@ -22,23 +25,22 @@ pub struct Atlas { } impl Atlas { - pub const ATLAS_SIZE: u32 = 4096; pub const RECT_PADDING: i32 = 6; - fn get_packer_config() -> rect_packer::Config { + fn get_packer_config(width: u32, height: u32) -> rect_packer::Config { rect_packer::Config { - width: Atlas::ATLAS_SIZE as i32, - height: Atlas::ATLAS_SIZE as i32, + width: width as i32, + height: height as i32, border_padding: Atlas::RECT_PADDING, rectangle_padding: Atlas::RECT_PADDING, } } - pub fn get_texture_desc() -> wgpu::TextureDescriptor<'static> { + pub fn get_texture_desc(width: u32, height: u32) -> wgpu::TextureDescriptor<'static> { let texture_size = wgpu::Extent3d { - width: Atlas::ATLAS_SIZE, - height: Atlas::ATLAS_SIZE, + width, + height, depth_or_array_layers: 1, }; @@ -56,10 +58,38 @@ impl Atlas { } } - pub fn new(device: &wgpu::Device, content: AtlasContent) -> Self { + pub fn new(device: &wgpu::Device, content: AtlasContent, width: u32, height: u32) -> Self { + let atlas_texture = Self::get_atlas_texture(device, &content, width, height); + + Self { + max_seen: 0, + width, + height, + packer: Packer::new(Atlas::get_packer_config(width, height)), + new_data: vec![], + atlas_texture, + area_used: 0, + did_clear: false, + content, + } + } + + pub fn resize(&mut self, device: &wgpu::Device, width: u32, height: u32) { + self.width = width; + self.height = height; + self.atlas_texture = Self::get_atlas_texture(device, &self.content, width, height); + self.clear(); + } + + fn get_atlas_texture( + device: &wgpu::Device, + content: &AtlasContent, + width: u32, + height: u32, + ) -> wgpu::Texture { let texture_size = wgpu::Extent3d { - width: Atlas::ATLAS_SIZE, - height: Atlas::ATLAS_SIZE, + width, + height, depth_or_array_layers: 1, }; let format = match content { @@ -78,19 +108,14 @@ impl Atlas { label: Some("atlas_texture"), view_formats: &[format], }; - let atlas_texture = device.create_texture(&desc); - - Self { - packer: Packer::new(Atlas::get_packer_config()), - new_data: vec![], - atlas_texture, - area_used: 0, - did_clear: false, - content, - } + device.create_texture(&desc) } pub fn add_region(&mut self, data: &[u8], width: u32, height: u32) -> Option { + let max_seen = width.max(height); + if max_seen > self.max_seen { + self.max_seen = max_seen; + } if let Some(rect) = self.packer.pack(width as i32, height as i32, false) { self.new_data.push(ImageData { rect, @@ -109,28 +134,30 @@ impl Atlas { if self.did_clear { // encoder.clear_texture(&self.atlas_texture, &wgpu::ImageSubresourceRange::default()); - let sz = Atlas::ATLAS_SIZE as usize; + let image_size = wgpu::Extent3d { + width: self.width, + height: self.height, + depth_or_array_layers: 1, + }; - let data = vec![0_u8; sz * sz]; + let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT as i32; + let width = (self.width * 4) as i32; + let padding = (align - width % align) % align; + let padded_width = width + padding; + let padded_data = vec![0_u8; (padded_width as u32 * self.height) as usize]; let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("atlas temp buffer"), - contents: &data, + contents: &padded_data, usage: wgpu::BufferUsages::COPY_SRC | wgpu::BufferUsages::MAP_WRITE, }); - let image_size = wgpu::Extent3d { - width: sz as u32, - height: sz as u32, - depth_or_array_layers: 1, - }; - encoder.copy_buffer_to_texture( wgpu::ImageCopyBuffer { buffer: &buffer, layout: wgpu::ImageDataLayout { offset: 0, - bytes_per_row: std::num::NonZeroU32::new((sz * 4) as u32), + bytes_per_row: Some(padded_width as u32), rows_per_image: None, }, }, @@ -216,11 +243,11 @@ impl Atlas { } pub fn usage(&self) -> f32 { - (self.area_used as f32) / ((Atlas::ATLAS_SIZE * Atlas::ATLAS_SIZE) as f32) + (self.area_used as f32) / ((self.width * self.height) as f32) } pub fn clear(&mut self) { - self.packer = Packer::new(Atlas::get_packer_config()); + self.packer = Packer::new(Atlas::get_packer_config(self.width, self.height)); self.area_used = 0; self.new_data.clear(); self.did_clear = true; diff --git a/src/glyphs.rs b/src/glyphs.rs index ad5a394..9efacf8 100644 --- a/src/glyphs.rs +++ b/src/glyphs.rs @@ -30,12 +30,10 @@ pub struct Image { } pub struct GlyphCache { + pub size: u32, pub mask_atlas: Atlas, pub color_atlas: Atlas, - pub image_atlas: Atlas, - pub font: fontdue::Font, - info: HashMap<(char, u32), GlyphInfo>, - atlas_infos: HashMap< + glyph_infos: HashMap< ( cosmic_text::fontdb::ID, u16, @@ -50,18 +48,12 @@ pub struct GlyphCache { impl GlyphCache { pub fn new(device: &wgpu::Device) -> Self { - let mut settings = fontdue::FontSettings::default(); - settings.collection_index = 0; - settings.scale = 100.0; - let font = include_bytes!("fonts/Anodina-Regular.ttf") as &[u8]; - + let size = 1024; Self { - mask_atlas: Atlas::new(device, AtlasContent::Mask), - color_atlas: Atlas::new(device, AtlasContent::Color), - image_atlas: Atlas::new(device, AtlasContent::Color), - font: fontdue::Font::from_bytes(font, settings).unwrap(), - info: HashMap::new(), - atlas_infos: HashMap::new(), + size, + mask_atlas: Atlas::new(device, AtlasContent::Mask, size, size), + color_atlas: Atlas::new(device, AtlasContent::Color, size, size), + glyph_infos: HashMap::new(), img_infos: HashMap::new(), svg_infos: HashMap::new(), } @@ -120,7 +112,7 @@ impl GlyphCache { info } - pub fn get_glyph_mask<'a>( + pub fn get_glyph_mask( &mut self, font_id: cosmic_text::fontdb::ID, glyph_id: u16, @@ -129,7 +121,7 @@ impl GlyphCache { image: impl FnOnce() -> SwashImage, ) -> AtlasInfo { let key = (font_id, glyph_id, size, subpx); - if let Some(rect) = self.atlas_infos.get(&key) { + if let Some(rect) = self.glyph_infos.get(&key) { return *rect; } @@ -152,65 +144,37 @@ impl GlyphCache { top: image.placement.top, colored: image.content != SwashContent::Mask, }; - self.atlas_infos.insert(key, info); + self.glyph_infos.insert(key, info); info } - pub fn get_glyph(&mut self, c: char, size: f32) -> GlyphInfo { - let factor = 65536.0; - - // Convert size to fixed point so we can hash it. - let size_fixed_point = (size * factor) as u32; - - // Do we already have a glyph? - match self.info.get(&(c, size_fixed_point)) { - Some(info) => *info, - None => { - let (metrics, data) = self.font.rasterize(c, size_fixed_point as f32 / factor); - - /* - let mut i = 0; - for _ in 0..metrics.height { - for _ in 0..metrics.width { - print!("{} ", if data[i] != 0 { '*' } else { ' ' }); - i += 1; - } - print!("\n"); - } - */ - - let rect = - self.mask_atlas - .add_region(&data, metrics.width as u32, metrics.height as u32); - - let info = GlyphInfo { rect, metrics }; - - self.info.insert((c, size_fixed_point), info); - info - } - } - } - pub fn update(&mut self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder) { self.mask_atlas.update(device, encoder); self.color_atlas.update(device, encoder); - self.image_atlas.update(device, encoder); } - pub fn check_usage(&mut self) { - if self.mask_atlas.usage() > 0.7 - || self.color_atlas.usage() > 0.7 - || self.image_atlas.usage() > 0.7 - { + pub fn check_usage(&mut self, device: &wgpu::Device) -> bool { + let max_seen = (self.mask_atlas.max_seen as f32 * 2.0) + .max(self.color_atlas.max_seen as f32 * 2.0) as u32; + if max_seen > self.size { + self.size = max_seen; + self.mask_atlas.resize(device, self.size, self.size); + self.color_atlas.resize(device, self.size, self.size); + self.clear(); + true + } else if self.mask_atlas.usage() > 0.7 || self.color_atlas.usage() > 0.7 { self.clear(); + false + } else { + false } } pub fn clear(&mut self) { - self.info.clear(); self.mask_atlas.clear(); self.color_atlas.clear(); - self.image_atlas.clear(); - self.atlas_infos.clear(); + self.glyph_infos.clear(); + self.svg_infos.clear(); + self.img_infos.clear(); } } diff --git a/src/lib.rs b/src/lib.rs index 97cdd39..cccd9b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,4 @@ use cosmic_text::{SubpixelBin, SwashImage}; -use fontdue::layout::{CoordinateSystem, Layout, LayoutSettings, TextStyle}; use std::sync::Arc; mod path; @@ -36,6 +35,7 @@ use wgpu::util::DeviceExt; #[derive(Copy, Clone, Debug)] struct Uniforms { size: [f32; 2], + atlas_size: [f32; 2], } #[derive(Copy, Clone, Debug)] @@ -96,11 +96,10 @@ pub struct Vger { path_scanner: PathScanner, pen: LocalPoint, pub glyph_cache: GlyphCache, - layout: Layout, images: Vec>, image_bind_groups: Vec>, - image_bind_group_layout: wgpu::BindGroupLayout, - default_image_bind_group: wgpu::BindGroup, + cache_bind_group_layout: wgpu::BindGroupLayout, + cache_bind_group: wgpu::BindGroup, } impl Vger { @@ -139,16 +138,25 @@ impl Vger { wgpu::BindGroupLayoutEntry { binding: 1, visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Texture { - multisampled: false, - sample_type: wgpu::TextureSampleType::Float { filterable: true }, - view_dimension: wgpu::TextureViewDimension::D2, - }, + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), count: None, }, wgpu::BindGroupLayoutEntry { binding: 2, visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: None, + }, + ], + label: Some("uniform_bind_group_layout"), + }); + + let cache_bind_group_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, ty: wgpu::BindingType::Texture { multisampled: false, sample_type: wgpu::TextureSampleType::Float { filterable: true }, @@ -157,41 +165,21 @@ impl Vger { count: None, }, wgpu::BindGroupLayoutEntry { - binding: 3, - visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), - count: None, - }, - wgpu::BindGroupLayoutEntry { - binding: 4, + binding: 1, visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + ty: wgpu::BindingType::Texture { + multisampled: false, + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + view_dimension: wgpu::TextureViewDimension::D2, + }, count: None, }, ], - label: Some("uniform_bind_group_layout"), - }); - - let image_bind_group_layout = - device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - entries: &[wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Texture { - multisampled: false, - sample_type: wgpu::TextureSampleType::Float { filterable: true }, - view_dimension: wgpu::TextureViewDimension::D2, - }, - count: None, - }], label: Some("image_bind_group_layout"), }); let glyph_cache = GlyphCache::new(&device); - let mask_texture_view = glyph_cache.mask_atlas.create_view(); - let color_texture_view = glyph_cache.color_atlas.create_view(); - let uniforms = GPUVec::new_uniforms(&device, "uniforms"); let glyph_sampler = device.create_sampler(&wgpu::SamplerDescriptor { @@ -216,39 +204,25 @@ impl Vger { uniforms.bind_group_entry(0), wgpu::BindGroupEntry { binding: 1, - resource: wgpu::BindingResource::TextureView(&mask_texture_view), - }, - wgpu::BindGroupEntry { - binding: 2, - resource: wgpu::BindingResource::TextureView(&color_texture_view), - }, - wgpu::BindGroupEntry { - binding: 3, resource: wgpu::BindingResource::Sampler(&glyph_sampler), }, wgpu::BindGroupEntry { - binding: 4, + binding: 2, resource: wgpu::BindingResource::Sampler(&color_glyph_sampler), }, ], label: Some("vger bind group"), }); - let default_image_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &image_bind_group_layout, - entries: &[wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&texture_view), - }], - label: Some("vger default image bind group"), - }); + let cache_bind_group = + Self::get_cache_bind_group(&device, &glyph_cache, &cache_bind_group_layout); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, bind_group_layouts: &[ &Scene::bind_group_layout(&device), &uniform_bind_group_layout, - &image_bind_group_layout, + &cache_bind_group_layout, ], push_constant_ranges: &[], }); @@ -289,8 +263,6 @@ impl Vger { multiview: None, }); - let layout = Layout::new(CoordinateSystem::PositiveYUp); - Self { device, queue, @@ -310,23 +282,44 @@ impl Vger { path_scanner: PathScanner::new(), pen: LocalPoint::zero(), glyph_cache, - layout, images: vec![], image_bind_groups: vec![], - image_bind_group_layout, - default_image_bind_group, + cache_bind_group_layout, + cache_bind_group, } } + fn get_cache_bind_group( + device: &wgpu::Device, + glyph_cache: &GlyphCache, + bind_group_layout: &wgpu::BindGroupLayout, + ) -> wgpu::BindGroup { + let mask_texture_view = glyph_cache.mask_atlas.create_view(); + let color_texture_view = glyph_cache.color_atlas.create_view(); + + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&mask_texture_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::TextureView(&color_texture_view), + }, + ], + label: Some("vger cache bind group"), + }); + + bind_group + } + /// Begin rendering. pub fn begin(&mut self, window_width: f32, window_height: f32, device_px_ratio: f32) { self.device_px_ratio = device_px_ratio; self.cur_layer = 0; self.screen_size = ScreenSize::new(window_width, window_height); - self.uniforms.clear(); - self.uniforms.push(Uniforms { - size: [window_width, window_height], - }); self.cur_scene = (self.cur_scene + 1) % 3; self.scenes[self.cur_scene].clear(); self.tx_stack.clear(); @@ -338,6 +331,22 @@ impl Vger { self.add_xform(); self.scissor_count = 0; self.pen = LocalPoint::zero(); + + // If we're getting close to full, reset the glyph cache. + if self.glyph_cache.check_usage(&self.device) { + // if resized, we need to get new bind group + self.cache_bind_group = Self::get_cache_bind_group( + &self.device, + &self.glyph_cache, + &self.cache_bind_group_layout, + ) + } + + self.uniforms.clear(); + self.uniforms.push(Uniforms { + size: [window_width, window_height], + atlas_size: [self.glyph_cache.size as f32, self.glyph_cache.size as f32], + }); } /// Saves rendering state (transform and scissor rect). @@ -378,7 +387,7 @@ impl Vger { ); rpass.set_bind_group(1, &self.uniform_bind_group, &[]); - rpass.set_bind_group(2, &self.default_image_bind_group, &[]); + rpass.set_bind_group(2, &self.cache_bind_group, &[]); let scene = &self.scenes[self.cur_scene]; let n = scene.prims[self.cur_layer].len(); @@ -397,7 +406,7 @@ impl Vger { /*vertices*/ 0..4, /*instances*/ start..(start + m), ); - } + } current_texture = image_id; rpass.set_bind_group( @@ -423,9 +432,6 @@ impl Vger { } } queue.submit(Some(encoder.finish())); - - // If we're getting close to full, reset the glyph cache. - self.glyph_cache.check_usage(); } fn render(&mut self, prim: Prim) { @@ -675,23 +681,7 @@ impl Vger { self.path_scanner.segments.clear(); } - fn setup_layout(&mut self, text: &str, size: u32, max_width: Option) { - let scale = self.device_px_ratio; - - self.layout.reset(&LayoutSettings { - max_width: max_width.map(|w| w * scale), - ..LayoutSettings::default() - }); - - let scaled_size = size as f32 * scale; - - self.layout.append( - &[&self.glyph_cache.font], - &TextStyle::new(text, scaled_size, 0), - ); - } - - pub fn render_glyph<'a>( + pub fn render_glyph( &mut self, x: f32, y: f32, @@ -798,140 +788,6 @@ impl Vger { } } - /// Renders text. - pub fn text(&mut self, text: &str, size: u32, color: Color, max_width: Option) { - self.setup_layout(text, size, max_width); - - let scale = self.device_px_ratio; - let scaled_size = size as f32 * scale; - - let paint = self.color_paint(color); - let scissor = self.add_scissor() as u32; - - let mut prims = vec![]; - for (i, glyph) in self.layout.glyphs().iter().enumerate() { - let c = text.chars().nth(i).unwrap(); - // println!("glyph {:?}", c); - let info = self.glyph_cache.get_glyph(c, scaled_size); - - if let Some(rect) = info.rect { - let mut prim = Prim::default(); - prim.prim_type = PrimType::Glyph as u32; - prim.scissor = scissor; - assert!(glyph.width == rect.width as usize); - assert!(glyph.height == rect.height as usize); - - prim.quad_bounds = [ - glyph.x / scale, - glyph.y / scale, - (glyph.x + glyph.width as f32) / scale, - (glyph.y + glyph.height as f32) / scale, - ]; - // println!("quad_bounds: {:?}", prim.quad_bounds); - - prim.tex_bounds = [ - rect.x as f32, - (rect.y + rect.height) as f32, - (rect.x + rect.width) as f32, - rect.y as f32, - ]; - prim.paint = paint.index as u32; - // println!("tex_bounds: {:?}", prim.tex_bounds); - - prims.push(prim); - } - } - - for prim in prims { - self.render(prim); - } - } - - /// Calculates the bounds for text. - pub fn text_bounds(&mut self, text: &str, size: u32, max_width: Option) -> LocalRect { - self.setup_layout(text, size, max_width); - - let mut min = LocalPoint::new(f32::MAX, f32::MAX); - let mut max = LocalPoint::new(f32::MIN, f32::MIN); - - let scale = self.device_px_ratio; - - for glyph in self.layout.glyphs() { - min = min.min([glyph.x / scale, glyph.y / scale].into()); - max = max.max( - [ - (glyph.x + glyph.width as f32) / scale, - (glyph.y + glyph.height as f32) / scale, - ] - .into(), - ); - } - - LocalRect::new(min, (max - min).into()) - } - - /// Returns local coordinates of glyphs. - pub fn glyph_positions( - &mut self, - text: &str, - size: u32, - max_width: Option, - ) -> Vec { - let mut rects = vec![]; - rects.reserve(text.len()); - - self.setup_layout(text, size, max_width); - - let s = 1.0 / self.device_px_ratio; - - for glyph in self.layout.glyphs() { - rects.push( - LocalRect::new( - [glyph.x, glyph.y].into(), - [glyph.width as f32, glyph.height as f32].into(), - ) - .scale(s, s), - ) - } - - rects - } - - pub fn line_metrics( - &mut self, - text: &str, - size: u32, - max_width: Option, - ) -> Vec { - self.setup_layout(text, size, max_width); - let s = 1.0 / self.device_px_ratio; - - let mut rects = vec![]; - rects.reserve(text.len()); - - let glyphs = self.layout.glyphs(); - - if let Some(lines) = self.layout.lines() { - for line in lines { - let mut rect = LocalRect::zero(); - - for glyph in &glyphs[line.glyph_start..line.glyph_end] { - rect = rect.union(&LocalRect::new( - [glyph.x, glyph.y].into(), - [glyph.width as f32, glyph.height as f32].into(), - )); - } - rects.push(LineMetrics { - glyph_start: line.glyph_start, - glyph_end: line.glyph_end, - bounds: rect.scale(s, s), - }); - } - } - - rects - } - fn add_xform(&mut self) -> usize { if self.xform_count < MAX_PRIMS { let m = *self.tx_stack.last().unwrap(); @@ -1108,7 +964,7 @@ impl Vger { self.images.push(Some(texture)); let bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &self.image_bind_group_layout, + layout: &self.cache_bind_group_layout, entries: &[wgpu::BindGroupEntry { binding: 1, resource: wgpu::BindingResource::TextureView(&texture_view), diff --git a/src/shader.wgsl b/src/shader.wgsl index 6186b8f..c249520 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -510,10 +510,14 @@ struct VertexOutput { /// Point transformed by current transform. @location(2) p: vec2, + + /// Screen size. + @location(3) size: vec2, }; struct Uniforms { size: vec2, + atlas_size: vec2, }; @group(1) @@ -557,6 +561,7 @@ fn vs_main( out.p = (xforms.xforms[prim.xform] * vec4(q, 0.0, 1.0)).xy; out.position = vec4((2.0 * out.p / uniforms.size - 1.0) * vec2(1.0, -1.0), 0.0, 1.0); + out.size = uniforms.atlas_size; return out; } @@ -627,19 +632,20 @@ fn scissor_mask(scissor: Scissor, p: vec2) -> f32 { @group(1) @binding(1) -var glyph_atlas: texture_2d; +var samp : sampler; @group(1) @binding(2) -var color_atlas: texture_2d; +var color_samp : sampler; -@group(1) -@binding(3) -var samp : sampler; +@group(2) +@binding(0) +var glyph_atlas: texture_2d; + +@group(2) +@binding(1) +var color_atlas: texture_2d; -@group(1) -@binding(4) -var color_samp : sampler; // sRGB to linear conversion for one channel. fn toLinear(s: f32) -> f32 @@ -684,13 +690,13 @@ fn fs_main( // Look up glyph alpha (if not a glyph, still have to because of wgsl). // let a = textureSample(glyph_atlas, samp, (in.t+0.5)/1024.0).r; // let mask = textureLoad(glyph_atlas, vec2(in.t), 0); - let mask = textureSample(glyph_atlas, samp, in.t/4096.0); - let color_mask = textureSample(color_atlas, color_samp, in.t/4096.0); + let mask = textureSample(glyph_atlas, samp, in.t/in.size); + let color_mask = textureSample(color_atlas, color_samp, in.t/in.size); // Look up image color (if no active image, still have to because of wgsl). // Note that we could use a separate shader if that's a perf hit. let t = unpack_mat3x2(paint.xform) * vec3(in.t, 1.0); - var color = textureSample(tex, samp, t); + var color = vec4(0.0, 0.0, 0.0, 0.0); let s = scissor_mask(scissor, in.p); diff --git a/tests/tests.rs b/tests/tests.rs index 47120ac..5872a91 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -309,7 +309,6 @@ fn text() { vger.begin(512.0, 512.0, 1.0); vger.translate([32.0, 256.0]); - vger.text("This is a test", 32, Color::WHITE, None); let png_name = "text.png"; render_test(&mut vger, &device, &queue, png_name, true); @@ -329,7 +328,6 @@ fn text_small() { vger.begin(512.0, 512.0, 1.0); vger.translate([32.0, 256.0]); - vger.text("53", 18, Color::WHITE, None); let png_name = "text_small.png"; render_test(&mut vger, &device, &queue, png_name, true); @@ -338,7 +336,7 @@ fn text_small() { let atlas_png_name = "text_small_atlas.png"; save_png( &vger.glyph_cache.mask_atlas.atlas_texture, - &vger::atlas::Atlas::get_texture_desc(), + &vger::atlas::Atlas::get_texture_desc(1, 1), &device, &queue, atlas_png_name, @@ -358,7 +356,6 @@ fn text_scale() { vger.begin(256.0, 256.0, 2.0); vger.translate([32.0, 128.0]); - vger.text("This is a test", 32, Color::WHITE, None); let png_name = "text_scale.png"; render_test(&mut vger, &device, &queue, png_name, true); @@ -367,7 +364,7 @@ fn text_scale() { let atlas_png_name = "text_scale_atlas.png"; save_png( &vger.glyph_cache.mask_atlas.atlas_texture, - &vger::atlas::Atlas::get_texture_desc(), + &vger::atlas::Atlas::get_texture_desc(1, 1), &device, &queue, atlas_png_name, @@ -392,12 +389,6 @@ fn text_box() { vger.translate([32.0, 256.0]); - let bounds = vger.text_bounds(lorem, 18, Some(448.0)); - - vger.stroke_rect(bounds.origin, bounds.max(), 10.0, 4.0, paint); - - vger.text(lorem, 18, Color::WHITE, Some(448.0)); - let png_name = "text_box.png"; render_test(&mut vger, &device, &queue, png_name, true); assert!(png_not_black(png_name)); @@ -405,7 +396,7 @@ fn text_box() { let atlas_png_name = "text_box_atlas.png"; save_png( &vger.glyph_cache.mask_atlas.atlas_texture, - &vger::atlas::Atlas::get_texture_desc(), + &vger::atlas::Atlas::get_texture_desc(1, 1), &device, &queue, atlas_png_name, @@ -452,12 +443,6 @@ fn test_scissor_text() { vger.translate([32.0, 256.0]); vger.scissor(euclid::rect(-100.0, -100.0, 400.0, 400.0), 0.0); - let bounds = vger.text_bounds(lorem, 18, Some(448.0)); - - vger.stroke_rect(bounds.origin, bounds.max(), 10.0, 4.0, paint); - - vger.text(lorem, 18, Color::WHITE, Some(448.0)); - let png_name = "text_box_scissor.png"; render_test(&mut vger, &device, &queue, png_name, true); assert!(png_not_black(png_name));