aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/gfx/font_context.rs8
-rw-r--r--components/gfx/lib.rs1
-rw-r--r--components/gfx/platform/freetype/font_context.rs81
-rw-r--r--components/gfx/platform/macos/font_context.rs8
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
+ }
+}