Compare commits

..
5 changed files with 26 additions and 23 deletions
+17 -1
View File
@@ -777,6 +777,14 @@ fn decode_frame(job: &FrameJob, pool: &Pool, stats: &mut DecodeStats) -> Result<
Ok((rf, pic))
}
/// Bytes all parallel tile states may hold of whole-frame CDEF and restoration metadata; past it
/// the tiles decode one after another on the frame's own metadata.
const TILE_METADATA_BUDGET: usize = 256 << 20;
fn tile_metadata_fits(tiles: usize, per_tile: usize) -> bool {
tiles.checked_mul(per_tile).is_some_and(|n| n <= TILE_METADATA_BUDGET)
}
/// Decode the tiles of a frame (tile number, data), in parallel when several; returns the final
/// CDFs of tile context_update_tile_id.
fn decode_tiles(pool: &Pool, fs: &mut FrameState, cdfs: &Cdfs, tiles: &[(usize, Vec<u8>)]) -> Result<Option<Box<Cdfs>>> {
@@ -790,7 +798,7 @@ fn decode_tiles(pool: &Pool, fs: &mut FrameState, cdfs: &Cdfs, tiles: &[(usize,
};
// Intra block copy reads the current frame through the tile's own buffer: keep whole-frame
// buffers (tiles one after another) for it.
if tiles.len() > 1 && pool.is_parallel() && !fs.fh.allow_intrabc {
if tiles.len() > 1 && pool.is_parallel() && !fs.fh.allow_intrabc && tile_metadata_fits(tiles.len(), fs.tile_metadata_bytes()) {
let mut states: Vec<TileState> = tiles
.iter()
.map(|(num, _)| {
@@ -1075,6 +1083,14 @@ mod guard_tests {
#[cfg(test)]
mod budget_tests {
use super::*;
#[test]
fn tile_metadata_copies_are_budgeted() {
assert!(tile_metadata_fits(64, 1 << 20));
assert!(!tile_metadata_fits(4096, 1 << 20));
assert!(!tile_metadata_fits(usize::MAX, 2));
}
use deckcraft_bitstream::budget::DECODE_MEMORY_BUDGET;
fn color(mono: bool) -> crate::header::ColorConfig {
+7
View File
@@ -253,6 +253,13 @@ impl FrameState {
self.lr = t.lr;
}
/// Bytes of CDEF and loop-restoration metadata each parallel tile state copies whole.
pub fn tile_metadata_bytes(&self) -> usize {
let lr = &self.lr;
// 1 (type) + 6 (Wiener) + 1 (SGR set) + 2 (SGR weights) bytes per unit.
self.cdef.len() + lr.lr_type.iter().map(|v| v.len() * 10).sum::<usize>()
}
/// Private buffers for the tile covering mode info rows [r0, r1) x columns [c0, c1); tiles
/// on the right / bottom frame edge also cover the allocation margins.
pub fn tile_state(&self, r0: usize, r1: usize, c0: usize, c1: usize) -> TileState {
+1 -1
View File
@@ -169,7 +169,7 @@ impl FontDb {
if bundled.contains(fam) {
continue;
}
if self.is_loaded(fam) || (self.system_fallback_enabled() && self.has_family(fam)) {
if self.is_loaded(fam) || self.has_family(fam) {
let f = self.face(fam, style);
if f.family.eq_ignore_ascii_case(fam) && covers_cluster(&f, cluster) {
return f;
+1 -13
View File
@@ -976,17 +976,6 @@ impl FontDb {
let _ = on;
}
/// Whether automatic system-font lookups (fallback by character, symbol and script families)
/// may touch installed fonts. Lookups of a family the document or host names are not gated.
pub(crate) fn system_fallback_enabled(&self) -> bool {
#[cfg(not(target_arch = "wasm32"))]
{
self.sys.lock().unwrap_or_else(std::sync::PoisonError::into_inner).enabled
}
#[cfg(target_arch = "wasm32")]
false
}
/// Process-wide database: the bundled fonts, then the installed system fonts, cataloged the
/// first time a lookup by family name needs them (or ahead of time by
/// [`FontDb::scan_in_background`]).
@@ -1480,8 +1469,7 @@ impl FontDb {
};
#[cfg(not(target_arch = "wasm32"))]
{
let cataloged: Vec<String> =
if self.system_fallback_enabled() { self.read_catalog().iter().map(|e| e.family.clone()).collect() } else { Vec::new() };
let cataloged: Vec<String> = self.read_catalog().iter().map(|e| e.family.clone()).collect();
for fam in SYSTEM_FALLBACKS.iter().filter(|f| f.contains("Symbol")) {
if !self.is_loaded(fam) && cataloged.iter().any(|f| f.eq_ignore_ascii_case(fam)) {
self.load_cataloged(fam);
-8
View File
@@ -425,11 +425,3 @@ fn the_font_scan_skips_fifos_folders_and_link_loops() {
assert!(fifo || n >= 1);
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn disabling_system_fallback_gates_automatic_family_loads() {
let db = FontDb::with_font_dirs(Vec::new());
assert!(cfg!(target_arch = "wasm32") || db.system_fallback_enabled());
db.set_system_fallback(false);
assert!(!db.system_fallback_enabled());
}