Stop leaking glyph buffers

This commit is contained in:
Patrick Walton 2017-01-27 11:31:24 -08:00
parent 04ae5651ec
commit 8fbb875654
3 changed files with 32 additions and 15 deletions

View File

@ -18,8 +18,7 @@ use memmap::{Mmap, Protection};
use pathfinder::batch::BatchBuilder; use pathfinder::batch::BatchBuilder;
use pathfinder::charmap::CodepointRanges; use pathfinder::charmap::CodepointRanges;
use pathfinder::coverage::CoverageBuffer; use pathfinder::coverage::CoverageBuffer;
use pathfinder::glyph_buffer::GlyphBufferBuilder; use pathfinder::glyph_buffer::{GlyphBufferBuilder, GlyphBuffers};
use pathfinder::glyph_range::GlyphRanges;
use pathfinder::otf::Font; use pathfinder::otf::Font;
use pathfinder::rasterizer::{Rasterizer, RasterizerOptions}; use pathfinder::rasterizer::{Rasterizer, RasterizerOptions};
use pathfinder::shaper; use pathfinder::shaper;
@ -92,11 +91,20 @@ fn main() {
let mut point_size = INITIAL_POINT_SIZE; let mut point_size = INITIAL_POINT_SIZE;
let mut dirty = true; let mut dirty = true;
let mut glyph_buffer_builder = GlyphBufferBuilder::new();
let mut glyph_count = 0;
for glyph_id in glyph_ranges.iter() {
glyph_buffer_builder.add_glyph(&font, glyph_id).unwrap();
glyph_count += 1
}
let glyph_buffers = glyph_buffer_builder.create_buffers().unwrap();
while !window.should_close() { while !window.should_close() {
if dirty { if dirty {
renderer.redraw(&font, renderer.redraw(point_size,
point_size, &glyph_buffer_builder,
&glyph_ranges, &glyph_buffers,
glyph_count,
&glyph_positions, &glyph_positions,
&device_pixel_size); &device_pixel_size);
window.swap_buffers(); window.swap_buffers();
@ -263,30 +271,28 @@ impl Renderer {
} }
fn redraw(&self, fn redraw(&self,
font: &Font,
point_size: f32, point_size: f32,
glyph_ranges: &GlyphRanges, glyph_buffer_builder: &GlyphBufferBuilder,
glyph_buffers: &GlyphBuffers,
glyph_count: usize,
glyph_positions: &[GlyphPos], glyph_positions: &[GlyphPos],
device_pixel_size: &Size2D<u32>) { device_pixel_size: &Size2D<u32>) {
// FIXME(pcwalton) // FIXME(pcwalton)
let shelf_height = (point_size * 2.0).ceil() as u32; let shelf_height = (point_size * 2.0).ceil() as u32;
let mut glyph_buffer_builder = GlyphBufferBuilder::new();
let mut batch_builder = BatchBuilder::new(device_pixel_size.width, shelf_height); let mut batch_builder = BatchBuilder::new(device_pixel_size.width, shelf_height);
for (glyph_index, glyph_id) in glyph_ranges.iter().enumerate() { for glyph_index in 0..(glyph_count as u32) {
glyph_buffer_builder.add_glyph(&font, glyph_id).unwrap(); batch_builder.add_glyph(&glyph_buffer_builder, glyph_index, point_size).unwrap()
batch_builder.add_glyph(&glyph_buffer_builder, glyph_index as u32, point_size).unwrap()
} }
let glyph_buffer = glyph_buffer_builder.create_buffers().unwrap(); let batch = batch_builder.create_batch(&glyph_buffer_builder).unwrap();
let batch = batch_builder.finish(&glyph_buffer_builder).unwrap();
let pixels_per_unit = point_size as f32 / UNITS_PER_EM as f32; let pixels_per_unit = point_size as f32 / UNITS_PER_EM as f32;
self.rasterizer.draw_atlas(&Rect::new(Point2D::new(0, 0), self.atlas_size), self.rasterizer.draw_atlas(&Rect::new(Point2D::new(0, 0), self.atlas_size),
shelf_height, shelf_height,
&glyph_buffer, glyph_buffers,
&batch, &batch,
&self.coverage_buffer, &self.coverage_buffer,
&self.compute_texture).unwrap(); &self.compute_texture).unwrap();

View File

@ -67,7 +67,8 @@ impl BatchBuilder {
Ok(()) Ok(())
} }
pub fn finish(&mut self, glyph_buffer_builder: &GlyphBufferBuilder) -> Result<Batch, ()> { pub fn create_batch(&mut self, glyph_buffer_builder: &GlyphBufferBuilder)
-> Result<Batch, ()> {
self.image_metadata.sort_by(|a, b| a.glyph_index.cmp(&b.glyph_index)); self.image_metadata.sort_by(|a, b| a.glyph_index.cmp(&b.glyph_index));
let (mut current_range, mut counts, mut start_indices) = (None, vec![], vec![]); let (mut current_range, mut counts, mut start_indices) = (None, vec![], vec![]);

View File

@ -129,6 +129,16 @@ pub struct GlyphBuffers {
pub descriptors: GLuint, pub descriptors: GLuint,
} }
impl Drop for GlyphBuffers {
fn drop(&mut self) {
unsafe {
gl::DeleteBuffers(1, &mut self.descriptors);
gl::DeleteBuffers(1, &mut self.indices);
gl::DeleteBuffers(1, &mut self.vertices);
}
}
}
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct GlyphDescriptor { pub struct GlyphDescriptor {