Skip to content

Commit

Permalink
Auto merge of #18322 - glennw:update-wr-fonts-2, r=emilio
Browse files Browse the repository at this point in the history
Update WR (font instance API).

WR now has a concept of font templates and font instances. This
makes the WR font interfaces closer to Cairo and Gecko, and also
makes some future performance optimizations possible.

A font template is the font family, and data backing the font.
A font instance is a reference to a font template and per-instance
options, such as font size, anti-aliasing settings etc.

To update Servo in a minimally invasive way, I added a new font
cache call, that creates a font instance. This means that when
a font is created, and doesn't exist in the cache there are now
two calls to the font cache thread. We could refactor the font
cache to make this work in one call, which we should do in the
future. However, refactoring the font cache is a large chunk of
work by itself. The extra call is only when a font doesn't already
exist in the font context cache, so it should have minimal
performance impact.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18322)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Sep 1, 2017
2 parents e10e569 + b015e93 commit f7d238d
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 103 deletions.
56 changes: 28 additions & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions components/gfx/font.rs
Expand Up @@ -112,7 +112,7 @@ pub struct Font {
shaper: Option<Shaper>,
shape_cache: RefCell<HashMap<ShapeCacheEntry, Arc<GlyphStore>>>,
glyph_advance_cache: RefCell<HashMap<u32, FractionalPixel>>,
pub font_key: webrender_api::FontKey,
pub font_key: webrender_api::FontInstanceKey,
}

impl Font {
Expand All @@ -121,7 +121,7 @@ impl Font {
descriptor: FontTemplateDescriptor,
requested_pt_size: Au,
actual_pt_size: Au,
font_key: webrender_api::FontKey) -> Font {
font_key: webrender_api::FontInstanceKey) -> Font {
let metrics = handle.metrics();
Font {
handle: handle,
Expand Down
79 changes: 56 additions & 23 deletions components/gfx/font_cache_thread.rs
Expand Up @@ -2,6 +2,7 @@
* 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 app_units::Au;
use font_template::{FontTemplate, FontTemplateDescriptor};
use fontsan;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
Expand Down Expand Up @@ -36,7 +37,7 @@ struct FontTemplates {
#[derive(Debug, Deserialize, Serialize)]
pub struct FontTemplateInfo {
pub font_template: Arc<FontTemplateData>,
pub font_key: Option<webrender_api::FontKey>,
pub font_key: webrender_api::FontKey,
}

impl FontTemplates {
Expand Down Expand Up @@ -106,6 +107,7 @@ impl FontTemplates {
pub enum Command {
GetFontTemplate(FontFamily, FontTemplateDescriptor, IpcSender<Reply>),
GetLastResortFontTemplate(FontTemplateDescriptor, IpcSender<Reply>),
GetFontInstance(webrender_api::FontKey, Au, IpcSender<webrender_api::FontInstanceKey>),
AddWebFont(LowercaseString, EffectiveSources, IpcSender<()>),
AddDownloadedWebFont(LowercaseString, ServoUrl, Vec<u8>, IpcSender<()>),
Exit(IpcSender<()>),
Expand All @@ -127,8 +129,9 @@ struct FontCache {
web_families: HashMap<LowercaseString, FontTemplates>,
font_context: FontContextHandle,
core_resource_thread: CoreResourceThread,
webrender_api: Option<webrender_api::RenderApi>,
webrender_api: webrender_api::RenderApi,
webrender_fonts: HashMap<Atom, webrender_api::FontKey>,
font_instances: HashMap<(webrender_api::FontKey, Au), webrender_api::FontInstanceKey>,
}

fn populate_generic_fonts() -> HashMap<FontFamily, LowercaseString> {
Expand Down Expand Up @@ -172,6 +175,25 @@ impl FontCache {
let font_template = self.last_resort_font_template(&descriptor);
let _ = result.send(Reply::GetFontTemplateReply(Some(font_template)));
}
Command::GetFontInstance(font_key, size, result) => {
let webrender_api = &self.webrender_api;

let instance_key = *self.font_instances
.entry((font_key, size))
.or_insert_with(|| {
let key = webrender_api.generate_font_instance_key();
let mut updates = webrender_api::ResourceUpdates::new();
updates.add_font_instance(key,
font_key,
size,
None,
None);
webrender_api.update_resources(updates);
key
});

let _ = result.send(instance_key);
}
Command::AddWebFont(family_name, sources, result) => {
self.handle_add_web_font(family_name, sources, result);
}
Expand Down Expand Up @@ -342,22 +364,20 @@ impl FontCache {
}

fn get_font_template_info(&mut self, template: Arc<FontTemplateData>) -> FontTemplateInfo {
let mut font_key = None;

if let Some(ref webrender_api) = self.webrender_api {
let webrender_fonts = &mut self.webrender_fonts;
font_key = Some(*webrender_fonts.entry(template.identifier.clone()).or_insert_with(|| {
let font_key = webrender_api.generate_font_key();
let mut updates = webrender_api::ResourceUpdates::new();
match (template.bytes_if_in_memory(), template.native_font()) {
(Some(bytes), _) => updates.add_raw_font(font_key, bytes, 0),
(None, Some(native_font)) => updates.add_native_font(font_key, native_font),
(None, None) => updates.add_raw_font(font_key, template.bytes().clone(), 0),
}
webrender_api.update_resources(updates);
font_key
}));
}
let webrender_api = &self.webrender_api;
let webrender_fonts = &mut self.webrender_fonts;

let font_key = *webrender_fonts.entry(template.identifier.clone()).or_insert_with(|| {
let font_key = webrender_api.generate_font_key();
let mut updates = webrender_api::ResourceUpdates::new();
match (template.bytes_if_in_memory(), template.native_font()) {
(Some(bytes), _) => updates.add_raw_font(font_key, bytes, 0),
(None, Some(native_font)) => updates.add_native_font(font_key, native_font),
(None, None) => updates.add_raw_font(font_key, template.bytes().clone(), 0),
}
webrender_api.update_resources(updates);
font_key
});

FontTemplateInfo {
font_template: template,
Expand Down Expand Up @@ -403,7 +423,7 @@ pub struct FontCacheThread {

impl FontCacheThread {
pub fn new(core_resource_thread: CoreResourceThread,
webrender_api: Option<webrender_api::RenderApi>) -> FontCacheThread {
webrender_api: webrender_api::RenderApi) -> FontCacheThread {
let (chan, port) = ipc::channel().unwrap();

let channel_to_self = chan.clone();
Expand All @@ -413,14 +433,15 @@ impl FontCacheThread {

let mut cache = FontCache {
port: port,
channel_to_self: channel_to_self,
generic_fonts: generic_fonts,
channel_to_self,
generic_fonts,
local_families: HashMap::new(),
web_families: HashMap::new(),
font_context: FontContextHandle::new(),
core_resource_thread: core_resource_thread,
webrender_api: webrender_api,
core_resource_thread,
webrender_api,
webrender_fonts: HashMap::new(),
font_instances: HashMap::new(),
};

cache.refresh_local_families();
Expand Down Expand Up @@ -470,6 +491,18 @@ impl FontCacheThread {
self.chan.send(Command::AddWebFont(LowercaseString::new(&family.name), sources, sender)).unwrap();
}

pub fn get_font_instance(&self, key: webrender_api::FontKey, size: Au) -> webrender_api::FontInstanceKey {
let (response_chan, response_port) =
ipc::channel().expect("failed to create IPC channel");
self.chan.send(Command::GetFontInstance(key, size, response_chan))
.expect("failed to send message to font cache thread");

let instance_key = response_port.recv()
.expect("failed to receive response to font request");

instance_key
}

pub fn exit(&self) {
let (response_chan, response_port) = ipc::channel().unwrap();
self.chan.send(Command::Exit(response_chan)).expect("Couldn't send FontCacheThread exit message");
Expand Down

0 comments on commit f7d238d

Please sign in to comment.