mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
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.
This commit is contained in:
parent
9a9866117a
commit
b015e93dc5
9 changed files with 92 additions and 102 deletions
|
@ -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};
|
||||
|
@ -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 {
|
||||
|
@ -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<()>),
|
||||
|
@ -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> {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -342,22 +364,20 @@ impl FontCache {
|
|||
}
|
||||
|
||||
fn get_font_template_info(&mut self, template: Arc<FontTemplateData>) -> FontTemplateInfo {
|
||||
let mut font_key = None;
|
||||
let webrender_api = &self.webrender_api;
|
||||
let webrender_fonts = &mut self.webrender_fonts;
|
||||
|
||||
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 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,
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue