Speed up `lorem-ipsum`, especially in debug builds
This commit is contained in:
parent
45ade674be
commit
7862bec2bb
|
@ -35,6 +35,7 @@ use std::mem;
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
const ATLAS_SIZE: u32 = 2048;
|
const ATLAS_SIZE: u32 = 2048;
|
||||||
const WIDTH: u32 = 640;
|
const WIDTH: u32 = 640;
|
||||||
|
@ -197,9 +198,8 @@ impl DemoApp {
|
||||||
println!("wrote screenshot to: {}", ATLAS_DUMP_FILENAME);
|
println!("wrote screenshot to: {}", ATLAS_DUMP_FILENAME);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
WindowEvent::Scroll(x, y) => {
|
WindowEvent::Scroll(_, y) if self.window.get_key(Key::LeftAlt) == Action::Press ||
|
||||||
if self.window.get_key(Key::LeftAlt) == Action::Press ||
|
self.window.get_key(Key::RightAlt) == Action::Press => {
|
||||||
self.window.get_key(Key::RightAlt) == Action::Press {
|
|
||||||
let old_point_size = self.point_size;
|
let old_point_size = self.point_size;
|
||||||
self.point_size = old_point_size + y as f32;
|
self.point_size = old_point_size + y as f32;
|
||||||
|
|
||||||
|
@ -209,25 +209,19 @@ impl DemoApp {
|
||||||
self.point_size = MAX_POINT_SIZE
|
self.point_size = MAX_POINT_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut center =
|
let offset = Point2D::new(self.device_pixel_size.width as f32,
|
||||||
Point2D::new(self.translation.x as f32 -
|
self.device_pixel_size.height as f32);
|
||||||
self.device_pixel_size.width as f32 *
|
|
||||||
0.5,
|
|
||||||
self.translation.y as f32 -
|
|
||||||
self.device_pixel_size.height as f32 *
|
|
||||||
0.5);
|
|
||||||
center.x = center.x * self.point_size / old_point_size;
|
|
||||||
center.y = center.y * self.point_size / old_point_size;
|
|
||||||
|
|
||||||
self.translation.x =
|
let center = self.translation.cast().unwrap() - offset * 0.5;
|
||||||
(center.x + self.device_pixel_size.width as f32 * 0.5).round() as i32;
|
|
||||||
self.translation.y =
|
self.translation = (center * self.point_size / old_point_size +
|
||||||
(center.y + self.device_pixel_size.height as f32 * 0.5).round() as i32;
|
offset * 0.5).round().cast().unwrap();
|
||||||
} else {
|
|
||||||
self.translation.x += (x * SCROLL_SPEED).round() as i32;
|
true
|
||||||
self.translation.y += (y * SCROLL_SPEED).round() as i32;
|
|
||||||
}
|
}
|
||||||
|
WindowEvent::Scroll(x, y) => {
|
||||||
|
let vector = Point2D::new(x, y) * SCROLL_SPEED.round();
|
||||||
|
self.translation = self.translation + vector.cast().unwrap();
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
WindowEvent::Size(_, _) | WindowEvent::FramebufferSize(_, _) => {
|
WindowEvent::Size(_, _) | WindowEvent::FramebufferSize(_, _) => {
|
||||||
|
@ -604,30 +598,38 @@ impl Renderer {
|
||||||
scale,
|
scale,
|
||||||
SUBPIXEL_GRANULARITY);
|
SUBPIXEL_GRANULARITY);
|
||||||
|
|
||||||
let mut glyphs: Vec<_> = positioned_glyphs.iter().map(|positioned_glyph| {
|
let mut glyphs = vec![];
|
||||||
(positioned_glyph.glyph_index,
|
for positioned_glyph in &positioned_glyphs {
|
||||||
(positioned_glyph.subpixel_x / SUBPIXEL_GRANULARITY).round() as u8)
|
if positioned_glyph.glyph_index as usize >= glyphs.len() {
|
||||||
}).collect();
|
glyphs.resize(positioned_glyph.glyph_index as usize + 1, 0)
|
||||||
|
}
|
||||||
|
|
||||||
glyphs.sort();
|
let subpixel = (positioned_glyph.subpixel_x / SUBPIXEL_GRANULARITY).round() as u8;
|
||||||
glyphs.dedup();
|
glyphs[positioned_glyph.glyph_index as usize] |= 1 << subpixel
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cached_glyphs = vec![];
|
||||||
|
for (glyph_index, &subpixels) in glyphs.iter().enumerate() {
|
||||||
|
for subpixel in 0..SUBPIXEL_GRANULARITY_COUNT {
|
||||||
|
if (subpixels & (1 << subpixel)) == 0 {
|
||||||
|
cached_glyphs.push(CachedGlyph(Point2D::zero()));
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
let cached_glyphs = glyphs.iter().map(|&(glyph_index, subpixel)| {
|
|
||||||
let subpixel_offset = (subpixel as f32) / (SUBPIXEL_GRANULARITY as f32);
|
let subpixel_offset = (subpixel as f32) / (SUBPIXEL_GRANULARITY as f32);
|
||||||
let origin = atlas_builder.pack_glyph(&glyph_store.outlines,
|
let options = GlyphRasterizationOptions {
|
||||||
glyph_index,
|
|
||||||
&GlyphRasterizationOptions {
|
|
||||||
point_size: point_size,
|
point_size: point_size,
|
||||||
horizontal_offset: subpixel_offset,
|
horizontal_offset: subpixel_offset,
|
||||||
..GlyphRasterizationOptions::default()
|
..GlyphRasterizationOptions::default()
|
||||||
}).unwrap();
|
};
|
||||||
CachedGlyph {
|
|
||||||
x: origin.x,
|
let origin = atlas_builder.pack_glyph(&glyph_store.outlines,
|
||||||
y: origin.y,
|
glyph_index as u16,
|
||||||
glyph_index: glyph_index,
|
&options).unwrap();
|
||||||
subpixel: subpixel,
|
|
||||||
|
cached_glyphs.push(CachedGlyph(origin));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).collect();
|
|
||||||
|
|
||||||
(positioned_glyphs, cached_glyphs)
|
(positioned_glyphs, cached_glyphs)
|
||||||
}
|
}
|
||||||
|
@ -710,13 +712,11 @@ impl Renderer {
|
||||||
let glyph_rect_i = glyph_rect.round_out();
|
let glyph_rect_i = glyph_rect.round_out();
|
||||||
let glyph_size_i = glyph_rect_i.size();
|
let glyph_size_i = glyph_rect_i.size();
|
||||||
|
|
||||||
let cached_glyph_index = cached_glyphs.binary_search_by(|cached_glyph| {
|
let cached_glyph_index = glyph_index as usize * SUBPIXEL_GRANULARITY_COUNT as usize +
|
||||||
(cached_glyph.glyph_index, cached_glyph.subpixel).cmp(&(glyph_index, subpixel))
|
subpixel as usize;
|
||||||
}).expect("Didn't cache the glyph properly!");
|
|
||||||
let cached_glyph = cached_glyphs[cached_glyph_index];
|
let cached_glyph = cached_glyphs[cached_glyph_index];
|
||||||
|
|
||||||
let uv_tl: Point2D<u32> = Point2D::new(cached_glyph.x,
|
let uv_tl: Point2D<u32> = cached_glyph.0.floor().cast().unwrap();
|
||||||
cached_glyph.y).floor().cast().unwrap();
|
|
||||||
let uv_br = uv_tl + glyph_size_i.cast().unwrap();
|
let uv_br = uv_tl + glyph_size_i.cast().unwrap();
|
||||||
|
|
||||||
let left_pos = positioned_glyph.bounds.origin.x;
|
let left_pos = positioned_glyph.bounds.origin.x;
|
||||||
|
@ -808,27 +808,14 @@ impl Renderer {
|
||||||
|
|
||||||
let mut fps_atlas_builder = AtlasBuilder::new(&atlas_options);
|
let mut fps_atlas_builder = AtlasBuilder::new(&atlas_options);
|
||||||
|
|
||||||
let mut fps_glyphs = vec![];
|
let (fps_positioned_glyphs, fps_cached_glyphs) =
|
||||||
for &fps_glyph_index in &fps_glyph_store.all_glyph_indices {
|
self.determine_visible_glyphs(&mut fps_atlas_builder,
|
||||||
for subpixel in 0..SUBPIXEL_GRANULARITY_COUNT {
|
font,
|
||||||
let subpixel_increment = SUBPIXEL_GRANULARITY * subpixel as f32;
|
fps_glyph_store,
|
||||||
let options = GlyphRasterizationOptions {
|
&fps_typesetter,
|
||||||
point_size: FPS_DISPLAY_POINT_SIZE,
|
device_pixel_size,
|
||||||
horizontal_offset: subpixel_increment,
|
&Point2D::zero(),
|
||||||
..GlyphRasterizationOptions::default()
|
FPS_DISPLAY_POINT_SIZE);
|
||||||
};
|
|
||||||
|
|
||||||
let origin = fps_atlas_builder.pack_glyph(&fps_glyph_store.outlines,
|
|
||||||
fps_glyph_index,
|
|
||||||
&options).unwrap();
|
|
||||||
fps_glyphs.push(CachedGlyph {
|
|
||||||
x: origin.x,
|
|
||||||
y: origin.y,
|
|
||||||
glyph_index: fps_glyph_index,
|
|
||||||
subpixel: subpixel,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let fps_atlas = fps_atlas_builder.create_atlas().unwrap();
|
let fps_atlas = fps_atlas_builder.create_atlas().unwrap();
|
||||||
let rect = Rect::new(Point2D::new(0, 0), self.atlas_size);
|
let rect = Rect::new(Point2D::new(0, 0), self.atlas_size);
|
||||||
|
@ -846,20 +833,10 @@ impl Renderer {
|
||||||
let fps_left = FPS_PADDING;
|
let fps_left = FPS_PADDING;
|
||||||
let fps_top = device_pixel_size.height as i32 - FPS_PADDING - fps_line_spacing;
|
let fps_top = device_pixel_size.height as i32 - FPS_PADDING - fps_line_spacing;
|
||||||
|
|
||||||
let fps_viewport = Rect::new(Point2D::zero(), device_pixel_size.cast().unwrap());
|
|
||||||
let fps_scale = FPS_DISPLAY_POINT_SIZE / font.units_per_em() as f32;
|
|
||||||
|
|
||||||
let fps_positioned_glyphs =
|
|
||||||
fps_typesetter.positioned_glyphs_in_rect(&fps_viewport,
|
|
||||||
fps_glyph_store,
|
|
||||||
font.units_per_em() as f32,
|
|
||||||
fps_scale,
|
|
||||||
SUBPIXEL_GRANULARITY);
|
|
||||||
|
|
||||||
self.draw_glyphs(&fps_glyph_store,
|
self.draw_glyphs(&fps_glyph_store,
|
||||||
&self.fps_composite_vertex_array,
|
&self.fps_composite_vertex_array,
|
||||||
&fps_positioned_glyphs,
|
&fps_positioned_glyphs,
|
||||||
&fps_glyphs,
|
&fps_cached_glyphs,
|
||||||
device_pixel_size,
|
device_pixel_size,
|
||||||
&Point2D::new(fps_left, fps_top),
|
&Point2D::new(fps_left, fps_top),
|
||||||
self.fps_gl_texture,
|
self.fps_gl_texture,
|
||||||
|
@ -920,12 +897,7 @@ impl Vertex {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct CachedGlyph {
|
struct CachedGlyph(Point2D<f32>);
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
glyph_index: u16,
|
|
||||||
subpixel: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct CompositeVertexArray {
|
struct CompositeVertexArray {
|
||||||
|
|
Loading…
Reference in New Issue