mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 1612440 - Forward glyph dimension and index requests through the scene builder thread. r=gw
This prevents the request from racing ahead of the AddFontInstance message which follows the transaction through the scene builder thread and silently returning zero-sized glyphs. Differential Revision: https://phabricator.services.mozilla.com/D72906
This commit is contained in:
parent
7457a0c05c
commit
7716ebe2a3
@ -872,6 +872,25 @@ impl RenderBackend {
|
|||||||
|
|
||||||
self.bookkeep_after_frames();
|
self.bookkeep_after_frames();
|
||||||
},
|
},
|
||||||
|
SceneBuilderResult::GetGlyphDimensions(request) => {
|
||||||
|
let mut glyph_dimensions = Vec::with_capacity(request.glyph_indices.len());
|
||||||
|
if let Some(base) = self.resource_cache.get_font_instance(request.key) {
|
||||||
|
let font = FontInstance::from_base(Arc::clone(&base));
|
||||||
|
for glyph_index in &request.glyph_indices {
|
||||||
|
let glyph_dim = self.resource_cache.get_glyph_dimensions(&font, *glyph_index);
|
||||||
|
glyph_dimensions.push(glyph_dim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request.sender.send(glyph_dimensions).unwrap();
|
||||||
|
}
|
||||||
|
SceneBuilderResult::GetGlyphIndices(request) => {
|
||||||
|
let mut glyph_indices = Vec::with_capacity(request.text.len());
|
||||||
|
for ch in request.text.chars() {
|
||||||
|
let index = self.resource_cache.get_glyph_index(request.key, ch);
|
||||||
|
glyph_indices.push(index);
|
||||||
|
}
|
||||||
|
request.sender.send(glyph_indices).unwrap();
|
||||||
|
}
|
||||||
SceneBuilderResult::FlushComplete(tx) => {
|
SceneBuilderResult::FlushComplete(tx) => {
|
||||||
tx.send(()).ok();
|
tx.send(()).ok();
|
||||||
}
|
}
|
||||||
@ -1054,24 +1073,11 @@ impl RenderBackend {
|
|||||||
ApiMsg::FlushSceneBuilder(tx) => {
|
ApiMsg::FlushSceneBuilder(tx) => {
|
||||||
self.low_priority_scene_tx.send(SceneBuilderRequest::Flush(tx)).unwrap();
|
self.low_priority_scene_tx.send(SceneBuilderRequest::Flush(tx)).unwrap();
|
||||||
}
|
}
|
||||||
ApiMsg::GetGlyphDimensions(instance_key, glyph_indices, tx) => {
|
ApiMsg::GetGlyphDimensions(request) => {
|
||||||
let mut glyph_dimensions = Vec::with_capacity(glyph_indices.len());
|
self.scene_tx.send(SceneBuilderRequest::GetGlyphDimensions(request)).unwrap();
|
||||||
if let Some(base) = self.resource_cache.get_font_instance(instance_key) {
|
|
||||||
let font = FontInstance::from_base(Arc::clone(&base));
|
|
||||||
for glyph_index in &glyph_indices {
|
|
||||||
let glyph_dim = self.resource_cache.get_glyph_dimensions(&font, *glyph_index);
|
|
||||||
glyph_dimensions.push(glyph_dim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tx.send(glyph_dimensions).unwrap();
|
|
||||||
}
|
}
|
||||||
ApiMsg::GetGlyphIndices(font_key, text, tx) => {
|
ApiMsg::GetGlyphIndices(request) => {
|
||||||
let mut glyph_indices = Vec::new();
|
self.scene_tx.send(SceneBuilderRequest::GetGlyphIndices(request)).unwrap();
|
||||||
for ch in text.chars() {
|
|
||||||
let index = self.resource_cache.get_glyph_index(font_key, ch);
|
|
||||||
glyph_indices.push(index);
|
|
||||||
}
|
|
||||||
tx.send(glyph_indices).unwrap();
|
|
||||||
}
|
}
|
||||||
ApiMsg::CloneApi(sender) => {
|
ApiMsg::CloneApi(sender) => {
|
||||||
assert!(!self.namespace_alloc_by_client);
|
assert!(!self.namespace_alloc_by_client);
|
||||||
|
@ -6,7 +6,7 @@ use api::{AsyncBlobImageRasterizer, BlobImageRequest, BlobImageParams, BlobImage
|
|||||||
use api::{DocumentId, PipelineId, ApiMsg, FrameMsg, SceneMsg, ResourceUpdate, ExternalEvent};
|
use api::{DocumentId, PipelineId, ApiMsg, FrameMsg, SceneMsg, ResourceUpdate, ExternalEvent};
|
||||||
use api::{BuiltDisplayList, NotificationRequest, Checkpoint, IdNamespace, QualitySettings};
|
use api::{BuiltDisplayList, NotificationRequest, Checkpoint, IdNamespace, QualitySettings};
|
||||||
use api::{ClipIntern, FilterDataIntern, MemoryReport, PrimitiveKeyKind, SharedFontInstanceMap};
|
use api::{ClipIntern, FilterDataIntern, MemoryReport, PrimitiveKeyKind, SharedFontInstanceMap};
|
||||||
use api::DocumentLayer;
|
use api::{DocumentLayer, GlyphDimensionRequest, GlyphIndexRequest};
|
||||||
use api::units::*;
|
use api::units::*;
|
||||||
#[cfg(feature = "capture")]
|
#[cfg(feature = "capture")]
|
||||||
use crate::capture::CaptureConfig;
|
use crate::capture::CaptureConfig;
|
||||||
@ -123,6 +123,8 @@ pub enum SceneBuilderRequest {
|
|||||||
ExternalEvent(ExternalEvent),
|
ExternalEvent(ExternalEvent),
|
||||||
AddDocument(DocumentId, DeviceIntSize, DocumentLayer),
|
AddDocument(DocumentId, DeviceIntSize, DocumentLayer),
|
||||||
DeleteDocument(DocumentId),
|
DeleteDocument(DocumentId),
|
||||||
|
GetGlyphDimensions(GlyphDimensionRequest),
|
||||||
|
GetGlyphIndices(GlyphIndexRequest),
|
||||||
WakeUp,
|
WakeUp,
|
||||||
Flush(Sender<()>),
|
Flush(Sender<()>),
|
||||||
ClearNamespace(IdNamespace),
|
ClearNamespace(IdNamespace),
|
||||||
@ -150,6 +152,8 @@ pub enum SceneBuilderResult {
|
|||||||
ExternalEvent(ExternalEvent),
|
ExternalEvent(ExternalEvent),
|
||||||
FlushComplete(Sender<()>),
|
FlushComplete(Sender<()>),
|
||||||
ClearNamespace(IdNamespace),
|
ClearNamespace(IdNamespace),
|
||||||
|
GetGlyphDimensions(GlyphDimensionRequest),
|
||||||
|
GetGlyphIndices(GlyphIndexRequest),
|
||||||
Stopped,
|
Stopped,
|
||||||
DocumentsForDebugger(String)
|
DocumentsForDebugger(String)
|
||||||
}
|
}
|
||||||
@ -393,6 +397,12 @@ impl SceneBuilderThread {
|
|||||||
Ok(SceneBuilderRequest::ExternalEvent(evt)) => {
|
Ok(SceneBuilderRequest::ExternalEvent(evt)) => {
|
||||||
self.send(SceneBuilderResult::ExternalEvent(evt));
|
self.send(SceneBuilderResult::ExternalEvent(evt));
|
||||||
}
|
}
|
||||||
|
Ok(SceneBuilderRequest::GetGlyphDimensions(request)) => {
|
||||||
|
self.send(SceneBuilderResult::GetGlyphDimensions(request))
|
||||||
|
}
|
||||||
|
Ok(SceneBuilderRequest::GetGlyphIndices(request)) => {
|
||||||
|
self.send(SceneBuilderResult::GetGlyphIndices(request))
|
||||||
|
}
|
||||||
Ok(SceneBuilderRequest::Stop) => {
|
Ok(SceneBuilderRequest::Stop) => {
|
||||||
self.tx.send(SceneBuilderResult::Stopped).unwrap();
|
self.tx.send(SceneBuilderResult::Stopped).unwrap();
|
||||||
// We don't need to send a WakeUp to api_tx because we only
|
// We don't need to send a WakeUp to api_tx because we only
|
||||||
|
@ -986,13 +986,9 @@ pub enum DebugCommand {
|
|||||||
/// Message sent by the `RenderApi` to the render backend thread.
|
/// Message sent by the `RenderApi` to the render backend thread.
|
||||||
pub enum ApiMsg {
|
pub enum ApiMsg {
|
||||||
/// Gets the glyph dimensions
|
/// Gets the glyph dimensions
|
||||||
GetGlyphDimensions(
|
GetGlyphDimensions(font::GlyphDimensionRequest),
|
||||||
font::FontInstanceKey,
|
|
||||||
Vec<font::GlyphIndex>,
|
|
||||||
Sender<Vec<Option<font::GlyphDimensions>>>,
|
|
||||||
),
|
|
||||||
/// Gets the glyph indices from a string
|
/// Gets the glyph indices from a string
|
||||||
GetGlyphIndices(font::FontKey, String, Sender<Vec<Option<u32>>>),
|
GetGlyphIndices(font::GlyphIndexRequest),
|
||||||
/// Adds a new document namespace.
|
/// Adds a new document namespace.
|
||||||
CloneApi(Sender<IdNamespace>),
|
CloneApi(Sender<IdNamespace>),
|
||||||
/// Adds a new document namespace.
|
/// Adds a new document namespace.
|
||||||
@ -1487,20 +1483,28 @@ impl RenderApi {
|
|||||||
/// This means that glyph dimensions e.g. for spaces (' ') will mostly be None.
|
/// This means that glyph dimensions e.g. for spaces (' ') will mostly be None.
|
||||||
pub fn get_glyph_dimensions(
|
pub fn get_glyph_dimensions(
|
||||||
&self,
|
&self,
|
||||||
font: font::FontInstanceKey,
|
key: font::FontInstanceKey,
|
||||||
glyph_indices: Vec<font::GlyphIndex>,
|
glyph_indices: Vec<font::GlyphIndex>,
|
||||||
) -> Vec<Option<font::GlyphDimensions>> {
|
) -> Vec<Option<font::GlyphDimensions>> {
|
||||||
let (tx, rx) = channel();
|
let (sender, rx) = channel();
|
||||||
let msg = ApiMsg::GetGlyphDimensions(font, glyph_indices, tx);
|
let msg = ApiMsg::GetGlyphDimensions(font::GlyphDimensionRequest {
|
||||||
|
key,
|
||||||
|
glyph_indices,
|
||||||
|
sender
|
||||||
|
});
|
||||||
self.api_sender.send(msg).unwrap();
|
self.api_sender.send(msg).unwrap();
|
||||||
rx.recv().unwrap()
|
rx.recv().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the glyph indices for the supplied string. These
|
/// Gets the glyph indices for the supplied string. These
|
||||||
/// can be used to construct GlyphKeys.
|
/// can be used to construct GlyphKeys.
|
||||||
pub fn get_glyph_indices(&self, font_key: font::FontKey, text: &str) -> Vec<Option<u32>> {
|
pub fn get_glyph_indices(&self, key: font::FontKey, text: &str) -> Vec<Option<u32>> {
|
||||||
let (tx, rx) = channel();
|
let (sender, rx) = channel();
|
||||||
let msg = ApiMsg::GetGlyphIndices(font_key, text.to_string(), tx);
|
let msg = ApiMsg::GetGlyphIndices(font::GlyphIndexRequest {
|
||||||
|
key,
|
||||||
|
text: text.to_string(),
|
||||||
|
sender,
|
||||||
|
});
|
||||||
self.api_sender.send(msg).unwrap();
|
self.api_sender.send(msg).unwrap();
|
||||||
rx.recv().unwrap()
|
rx.recv().unwrap()
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ use std::cmp::Ordering;
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
use std::sync::{Arc, RwLock, RwLockReadGuard, mpsc::Sender};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
// local imports
|
// local imports
|
||||||
use crate::api::IdNamespace;
|
use crate::api::IdNamespace;
|
||||||
@ -210,6 +210,18 @@ pub struct GlyphDimensions {
|
|||||||
pub advance: f32,
|
pub advance: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct GlyphDimensionRequest {
|
||||||
|
pub key: FontInstanceKey,
|
||||||
|
pub glyph_indices: Vec<GlyphIndex>,
|
||||||
|
pub sender: Sender<Vec<Option<GlyphDimensions>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GlyphIndexRequest {
|
||||||
|
pub key: FontKey,
|
||||||
|
pub text: String,
|
||||||
|
pub sender: Sender<Vec<Option<u32>>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, Ord, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, Ord, PartialOrd)]
|
||||||
pub struct FontKey(pub IdNamespace, pub u32);
|
pub struct FontKey(pub IdNamespace, pub u32);
|
||||||
|
Loading…
Reference in New Issue
Block a user