diff options
-rw-r--r-- | components/gfx/font_context.rs | 8 | ||||
-rw-r--r-- | components/gfx/lib.rs | 1 | ||||
-rw-r--r-- | components/gfx/platform/freetype/font_context.rs | 81 | ||||
-rw-r--r-- | components/gfx/platform/macos/font_context.rs | 8 |
4 files changed, 85 insertions, 13 deletions
diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs index 4201e2ddc5f..27ba6c493df 100644 --- a/components/gfx/font_context.rs +++ b/components/gfx/font_context.rs @@ -16,6 +16,7 @@ use platform::font_template::FontTemplateData; use smallvec::SmallVec8; use util::cache::HashCache; use util::geometry::Au; +use util::mem::HeapSizeOf; use std::borrow::{self, ToOwned}; use std::cell::RefCell; @@ -285,6 +286,13 @@ impl FontContext { } } +impl HeapSizeOf for FontContext { + fn heap_size_of_children(&self) -> usize { + // FIXME(njn): Measure other fields eventually. + self.platform_handle.heap_size_of_children() + } +} + struct LayoutFontGroupCacheKey { pointer: Arc<SpecifiedFontStyle>, size: Au, diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs index 9465fcc871f..3117c8f7a6d 100644 --- a/components/gfx/lib.rs +++ b/components/gfx/lib.rs @@ -16,6 +16,7 @@ #[macro_use] extern crate log; +extern crate alloc; extern crate azure; #[macro_use] extern crate bitflags; extern crate fnv; diff --git a/components/gfx/platform/freetype/font_context.rs b/components/gfx/platform/freetype/font_context.rs index c60c6bf5e36..b8b70c2b42e 100644 --- a/components/gfx/platform/freetype/font_context.rs +++ b/components/gfx/platform/freetype/font_context.rs @@ -10,35 +10,72 @@ use freetype::freetype::FT_Memory; use freetype::freetype::FT_New_Library; use freetype::freetype::struct_FT_MemoryRec_; +use alloc::heap; use std::ptr; use std::rc::Rc; +use util::mem::{HeapSizeOf, heap_size_of}; -use libc::{self, c_void, c_long, size_t}; +use libc::{c_void, c_long}; -extern fn ft_alloc(_mem: FT_Memory, size: c_long) -> *mut c_void { +// We pass a |User| struct -- via an opaque |void*| -- to FreeType each time a new instance is +// created. FreeType passes it back to the ft_alloc/ft_realloc/ft_free callbacks. We use it to +// record the memory usage of each FreeType instance. +struct User { + size: usize, +} + +// FreeType doesn't require any particular alignment for allocations. +const FT_ALIGNMENT: usize = 0; + +extern fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void { unsafe { - let ptr = libc::malloc(size as size_t); - ptr as *mut c_void + let ptr = heap::allocate(req_size as usize, FT_ALIGNMENT) as *mut c_void; + let actual_size = heap_size_of(ptr); + + let user = (*mem).user as *mut User; + (*user).size += actual_size; + + ptr } } -extern fn ft_free(_mem: FT_Memory, block: *mut c_void) { +extern fn ft_free(mem: FT_Memory, ptr: *mut c_void) { unsafe { - libc::free(block); + let actual_size = heap_size_of(ptr); + + let user = (*mem).user as *mut User; + (*user).size -= actual_size; + + heap::deallocate(ptr as *mut u8, actual_size, FT_ALIGNMENT); } } -extern fn ft_realloc(_mem: FT_Memory, _cur_size: c_long, new_size: c_long, block: *mut c_void) -> *mut c_void { +extern fn ft_realloc(mem: FT_Memory, _cur_size: c_long, new_req_size: c_long, + old_ptr: *mut c_void) -> *mut c_void { unsafe { - let ptr = libc::realloc(block, new_size as size_t); - ptr as *mut c_void + let old_actual_size = heap_size_of(old_ptr); + let new_ptr = heap::reallocate(old_ptr as *mut u8, old_actual_size, + new_req_size as usize, FT_ALIGNMENT) as *mut c_void; + let new_actual_size = heap_size_of(new_ptr); + + let user = (*mem).user as *mut User; + (*user).size += new_actual_size - old_actual_size; + + new_ptr } } +// A |*mut User| field in a struct triggers a "use of `#[derive]` with a raw pointer" warning from +// rustc. But using a typedef avoids this, so... +pub type UserPtr = *mut User; + +// WARNING: We need to be careful how we use this struct. See the comment about Rc<> in +// FontContextHandle. #[derive(Clone)] pub struct FreeTypeLibraryHandle { pub ctx: FT_Library, - pub mem: FT_Memory, + mem: FT_Memory, + user: UserPtr, } impl Drop for FreeTypeLibraryHandle { @@ -47,19 +84,37 @@ impl Drop for FreeTypeLibraryHandle { unsafe { FT_Done_Library(self.ctx); Box::from_raw(self.mem); + Box::from_raw(self.user); } } } -#[derive(Clone)] +impl HeapSizeOf for FreeTypeLibraryHandle { + fn heap_size_of_children(&self) -> usize { + let ft_size = unsafe { (*self.user).size }; + ft_size + + heap_size_of(self.ctx as *const c_void) + + heap_size_of(self.mem as *const c_void) + + heap_size_of(self.user as *const c_void) + } +} + +#[derive(Clone, HeapSizeOf)] pub struct FontContextHandle { + // WARNING: FreeTypeLibraryHandle contains raw pointers, is clonable, and also implements + // `Drop`. This field needs to be Rc<> to make sure that the `drop` function is only called + // once, otherwise we'll get crashes. Yuk. pub ctx: Rc<FreeTypeLibraryHandle>, } impl FontContextHandle { pub fn new() -> FontContextHandle { + let user = box User { + size: 0, + }; + let user: *mut User = ::std::boxed::into_raw(user); let mem = box struct_FT_MemoryRec_ { - user: ptr::null_mut(), + user: user as *mut c_void, alloc: ft_alloc, free: ft_free, realloc: ft_realloc, @@ -74,7 +129,7 @@ impl FontContextHandle { FT_Add_Default_Modules(ctx); FontContextHandle { - ctx: Rc::new(FreeTypeLibraryHandle { ctx: ctx, mem: mem }), + ctx: Rc::new(FreeTypeLibraryHandle { ctx: ctx, mem: mem, user: user }), } } } diff --git a/components/gfx/platform/macos/font_context.rs b/components/gfx/platform/macos/font_context.rs index e35aadb9910..ca718de09ca 100644 --- a/components/gfx/platform/macos/font_context.rs +++ b/components/gfx/platform/macos/font_context.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use util::mem::HeapSizeOf; + #[derive(Clone)] pub struct FontContextHandle { ctx: () @@ -13,3 +15,9 @@ impl FontContextHandle { FontContextHandle { ctx: () } } } + +impl HeapSizeOf for FontContextHandle { + fn heap_size_of_children(&self) -> usize { + 0 + } +} |