Bug 1565569 - Remove the old pathfinder integration. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D37862

--HG--
extra : rebase_source : 93849386dacff73f73481e652e7e5a00f9d019fa
extra : source : 12d70adf7d1c28d0a4f7328c4b4659d4f33db107
This commit is contained in:
Nicolas Silva 2019-07-18 15:07:31 +02:00
Родитель 73076a77d0
Коммит 1f245ea240
21 изменённых файлов: 201 добавлений и 1307 удалений

106
gfx/wr/Cargo.lock сгенерированный
Просмотреть файл

@ -122,11 +122,6 @@ dependencies = [
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bit-vec"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.0.3"
@ -705,11 +700,6 @@ dependencies = [
"gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "half"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "httparse"
version = "1.2.4"
@ -869,14 +859,6 @@ dependencies = [
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.4.1"
@ -885,24 +867,6 @@ dependencies = [
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lyon_geom"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lyon_path"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lyon_geom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lzw"
version = "0.10.0"
@ -1172,63 +1136,6 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pathfinder_font_renderer"
version = "0.5.0"
source = "git+https://github.com/pcwalton/pathfinder?branch=webrender#e8805413321edf85870deee5678751746ed61316"
dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pathfinder_gfx_utils"
version = "0.2.0"
source = "git+https://github.com/pcwalton/pathfinder?branch=webrender#e8805413321edf85870deee5678751746ed61316"
dependencies = [
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pathfinder_partitioner"
version = "0.2.0"
source = "git+https://github.com/pcwalton/pathfinder?branch=webrender#e8805413321edf85870deee5678751746ed61316"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"half 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"lyon_geom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_path_utils 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)",
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pathfinder_path_utils"
version = "0.2.0"
source = "git+https://github.com/pcwalton/pathfinder?branch=webrender#e8805413321edf85870deee5678751746ed61316"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "peek-poke"
version = "0.2.0"
@ -1987,10 +1894,6 @@ dependencies = [
"malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_font_renderer 0.5.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)",
"pathfinder_gfx_utils 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)",
"pathfinder_partitioner 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)",
"pathfinder_path_utils 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)",
"plane-split 0.13.8 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2246,7 +2149,6 @@ dependencies = [
"checksum base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "621fc7ecb8008f86d7fb9b95356cd692ce9514b80a86d85b397f32a22da7b9e2"
"checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
"checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f"
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
"checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d"
@ -2312,7 +2214,6 @@ dependencies = [
"checksum glutin_gles2_sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "89996c30857ae1b4de4b5189abf1ea822a20a9fe9e1c93e5e7b862ff0bdd5cdf"
"checksum glutin_glx_sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1290a5ca5e46fcfa7f66f949cc9d9194b2cb6f2ed61892c8c2b82343631dba57"
"checksum glutin_wgl_sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f801bbc91efc22dd1c4818a47814fc72bf74d024510451b119381579bfa39021"
"checksum half 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d5c5f71a723d10dfc58927cbed37c3071a50afc7f073d86fd7d3e5727db890f"
"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"
"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
@ -2333,10 +2234,7 @@ dependencies = [
"checksum line_drawing 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9"
"checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd"
"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
"checksum lyon_geom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "216bfb2b880554865fa9deaa14671ab9f1368b942e7007cc8c97c083ac8a7f45"
"checksum lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9dc8e0746b7cca11960b602f7fe037bb067746a01eab4aa502fed1494544843"
"checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
"checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
"checksum malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35adee9ed962cf7d07d62cb58bc45029f3227f5b5b86246caa8632f06c187bc3"
@ -2368,10 +2266,6 @@ dependencies = [
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
"checksum pathfinder_font_renderer 0.5.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)" = "<none>"
"checksum pathfinder_gfx_utils 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)" = "<none>"
"checksum pathfinder_partitioner 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)" = "<none>"
"checksum pathfinder_path_utils 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)" = "<none>"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
"checksum plane-split 0.13.8 (registry+https://github.com/rust-lang/crates.io-index)" = "91c621d83b9c5a85b7ca7ca2bec643136debb327ad29d0a08768db1325780365"

Просмотреть файл

@ -17,4 +17,3 @@ build: false
test_script:
- cmd.exe /c ci-scripts\windows-tests.cmd
- cmd.exe /c ci-scripts\windows-pathfinder.cmd

Просмотреть файл

@ -31,7 +31,6 @@ cargo check ${CARGOFLAGS} --no-default-features
cargo check ${CARGOFLAGS} --no-default-features --features capture
cargo check ${CARGOFLAGS} --features capture,profiler
cargo check ${CARGOFLAGS} --features replay
cargo check ${CARGOFLAGS} --no-default-features --features pathfinder
popd
pushd wrench

Просмотреть файл

@ -1,14 +0,0 @@
:: This Source Code Form is subject to the terms of the Mozilla Public
:: 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/. */
:: This must be run from the root webrender directory!
:: Users may set the CARGOFLAGS environment variable to pass
:: additional flags to cargo if desired.
if NOT DEFINED CARGOFLAGS SET CARGOFLAGS=--verbose
pushd webrender
cargo check %CARGOFLAGS% --no-default-features --features pathfinder
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
popd

Просмотреть файл

@ -11,7 +11,6 @@ packages = [
"gl_generator",
"khronos_api",
"lazy_static",
"log",
"nix",
"parking_lot",
"parking_lot_core",

Просмотреть файл

@ -16,7 +16,6 @@ debugger = ["ws", "serde_json", "serde", "image_loader", "base64"]
capture = ["api/serialize", "ron", "serde", "smallvec/serde"]
replay = ["api/deserialize", "ron", "serde", "smallvec/serde"]
display_list_stats = ["api/display_list_stats"]
pathfinder = ["pathfinder_font_renderer", "pathfinder_gfx_utils", "pathfinder_partitioner", "pathfinder_path_utils"]
serialize_program = ["serde", "webrender_build/serialize_program"]
no_static_freetype = []
@ -54,28 +53,6 @@ malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of", package = "
ws = { optional = true, version = "0.8" }
svg_fmt = "0.4"
[dependencies.pathfinder_font_renderer]
git = "https://github.com/pcwalton/pathfinder"
branch = "webrender"
optional = true
# Uncomment to test FreeType on macOS:
# features = ["freetype"]
[dependencies.pathfinder_gfx_utils]
git = "https://github.com/pcwalton/pathfinder"
branch = "webrender"
optional = true
[dependencies.pathfinder_partitioner]
git = "https://github.com/pcwalton/pathfinder"
branch = "webrender"
optional = true
[dependencies.pathfinder_path_utils]
git = "https://github.com/pcwalton/pathfinder"
branch = "webrender"
optional = true
[dev-dependencies]
mozangle = "0.1"
rand = "0.4"

Просмотреть файл

@ -2,18 +2,13 @@
* 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/. */
#[cfg(feature = "pathfinder")]
use crate::api::units::DeviceIntPoint;
use crate::glyph_rasterizer::{FontInstance, GlyphFormat, GlyphKey, GlyphRasterizer};
use crate::internal_types::FastHashMap;
use crate::render_backend::{FrameId, FrameStamp};
use crate::render_task::RenderTaskCache;
#[cfg(feature = "pathfinder")]
use crate::render_task::RenderTaskCacheKey;
use crate::resource_cache::ResourceClassCache;
use std::sync::Arc;
use crate::texture_cache::{EvictionNotice, TextureCache};
#[cfg(not(feature = "pathfinder"))]
use crate::texture_cache::TextureCacheHandle;
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -21,12 +16,7 @@ use crate::texture_cache::TextureCacheHandle;
#[derive(Clone, Debug)]
pub struct CachedGlyphInfo {
pub format: GlyphFormat,
#[cfg(not(feature = "pathfinder"))]
pub texture_cache_handle: TextureCacheHandle,
#[cfg(feature = "pathfinder")]
pub render_task_cache_key: RenderTaskCacheKey,
#[cfg(feature = "pathfinder")]
pub origin: DeviceIntPoint,
}
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -43,26 +33,6 @@ pub enum GlyphCacheEntry {
}
impl GlyphCacheEntry {
#[cfg(feature = "pathfinder")]
fn get_allocated_size(&self, texture_cache: &TextureCache, render_task_cache: &RenderTaskCache)
-> Option<usize> {
match *self {
GlyphCacheEntry::Cached(ref glyph) => {
let render_task_cache_key = &glyph.render_task_cache_key;
render_task_cache.get_allocated_size_for_render_task(texture_cache,
&render_task_cache_key)
}
GlyphCacheEntry::Pending => Some(0),
// If the cache only has blank glyphs left, just get rid of it.
GlyphCacheEntry::Blank => None,
}
}
#[cfg(feature = "pathfinder")]
fn mark_unused(&self, _: &mut TextureCache) {
}
#[cfg(not(feature = "pathfinder"))]
fn get_allocated_size(&self, texture_cache: &TextureCache, _: &RenderTaskCache)
-> Option<usize> {
match *self {
@ -75,13 +45,11 @@ impl GlyphCacheEntry {
}
}
#[cfg(not(feature = "pathfinder"))]
fn mark_unused(&self, texture_cache: &mut TextureCache) {
if let GlyphCacheEntry::Cached(ref glyph) = *self {
texture_cache.mark_unused(&glyph.texture_cache_handle);
}
}
}
}}
#[allow(dead_code)]
#[cfg_attr(feature = "capture", derive(Serialize))]

Просмотреть файл

@ -6,11 +6,22 @@ use api::{FontInstanceFlags, FontInstancePlatformOptions};
use api::{FontKey, FontInstanceKey, FontRenderMode, FontTemplate, FontVariation};
use api::{ColorU, GlyphIndex, GlyphDimensions, SyntheticItalics};
use api::units::*;
use euclid::approxeq::ApproxEq;
use api::{ImageDescriptor, ImageFormat, DirtyRect};
use crate::internal_types::ResourceCacheError;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use crate::platform::font::FontContext;
use crate::device::TextureFilter;
use crate::gpu_types::UvRectKind;
use crate::glyph_cache::{GlyphCache, CachedGlyphInfo, GlyphCacheEntry};
use crate::resource_cache::CachedImageData;
use crate::texture_cache::{TextureCache, TextureCacheHandle, Eviction};
use crate::gpu_cache::GpuCache;
use crate::render_task::{RenderTaskGraph, RenderTaskCache};
use crate::profiler::TextureCacheProfileCounters;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use rayon::ThreadPool;
use rayon::prelude::*;
use euclid::approxeq::ApproxEq;
use euclid::size2;
use std::cmp;
use std::hash::{Hash, Hasher};
use std::mem;
@ -18,15 +29,181 @@ use std::ops::Deref;
use std::sync::{Arc, Condvar, Mutex, MutexGuard};
use std::sync::mpsc::{channel, Receiver, Sender};
#[cfg(feature = "pathfinder")]
mod pathfinder;
#[cfg(feature = "pathfinder")]
use self::pathfinder::create_pathfinder_font_context;
#[cfg(feature = "pathfinder")]
pub use self::pathfinder::{ThreadSafePathfinderFontContext, NativeFontHandleWrapper};
impl FontContexts {
/// Get access to the font context associated to the current thread.
pub fn lock_current_context(&self) -> MutexGuard<FontContext> {
let id = self.current_worker_id();
self.lock_context(id)
}
#[cfg(not(feature = "pathfinder"))]
mod no_pathfinder;
pub(in super) fn current_worker_id(&self) -> Option<usize> {
self.workers.current_thread_index()
}
}
impl GlyphRasterizer {
pub fn request_glyphs(
&mut self,
glyph_cache: &mut GlyphCache,
font: FontInstance,
glyph_keys: &[GlyphKey],
texture_cache: &mut TextureCache,
gpu_cache: &mut GpuCache,
_: &mut RenderTaskCache,
_: &mut RenderTaskGraph,
) {
assert!(
self.font_contexts
.lock_shared_context()
.has_font(&font.font_key)
);
let mut new_glyphs = Vec::new();
let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font_mut(font.clone());
// select glyphs that have not been requested yet.
for key in glyph_keys {
if let Some(entry) = glyph_key_cache.try_get(key) {
match entry {
GlyphCacheEntry::Cached(ref glyph) => {
// Skip the glyph if it is already has a valid texture cache handle.
if !texture_cache.request(&glyph.texture_cache_handle, gpu_cache) {
continue;
}
// This case gets hit when we already rasterized the glyph, but the
// glyph has been evicted from the texture cache. Just force it to
// pending so it gets rematerialized.
}
// Otherwise, skip the entry if it is blank or pending.
GlyphCacheEntry::Blank | GlyphCacheEntry::Pending => continue,
}
}
new_glyphs.push(key.clone());
glyph_key_cache.add_glyph(key.clone(), GlyphCacheEntry::Pending);
}
if new_glyphs.is_empty() {
return;
}
self.pending_glyphs += 1;
self.request_glyphs_from_backend(font, new_glyphs);
}
pub(in super) fn request_glyphs_from_backend(&mut self, font: FontInstance, glyphs: Vec<GlyphKey>) {
let font_contexts = Arc::clone(&self.font_contexts);
let glyph_tx = self.glyph_tx.clone();
// spawn an async task to get off of the render backend thread as early as
// possible and in that task use rayon's fork join dispatch to rasterize the
// glyphs in the thread pool.
self.workers.spawn(move || {
let jobs = glyphs
.par_iter()
.map(|key: &GlyphKey| {
profile_scope!("glyph-raster");
let mut context = font_contexts.lock_current_context();
let mut job = GlyphRasterJob {
key: key.clone(),
result: context.rasterize_glyph(&font, key),
};
if let Ok(ref mut glyph) = job.result {
// Sanity check.
let bpp = 4; // We always render glyphs in 32 bits RGBA format.
assert_eq!(
glyph.bytes.len(),
bpp * (glyph.width * glyph.height) as usize
);
assert_eq!((glyph.left.fract(), glyph.top.fract()), (0.0, 0.0));
// Check if the glyph has a bitmap that needs to be downscaled.
glyph.downscale_bitmap_if_required(&font);
}
job
})
.collect();
glyph_tx.send(GlyphRasterJobs { font, jobs }).unwrap();
});
}
pub fn resolve_glyphs(
&mut self,
glyph_cache: &mut GlyphCache,
texture_cache: &mut TextureCache,
gpu_cache: &mut GpuCache,
_: &mut RenderTaskCache,
_: &mut RenderTaskGraph,
_: &mut TextureCacheProfileCounters,
) {
// Pull rasterized glyphs from the queue and update the caches.
while self.pending_glyphs > 0 {
self.pending_glyphs -= 1;
// TODO: rather than blocking until all pending glyphs are available
// we could try_recv and steal work from the thread pool to take advantage
// of the fact that this thread is alive and we avoid the added latency
// of blocking it.
let GlyphRasterJobs { font, mut jobs } = self.glyph_rx
.recv()
.expect("BUG: Should be glyphs pending!");
// Ensure that the glyphs are always processed in the same
// order for a given text run (since iterating a hash set doesn't
// guarantee order). This can show up as very small float inaccuracy
// differences in rasterizers due to the different coordinates
// that text runs get associated with by the texture cache allocator.
jobs.sort_by(|a, b| a.key.cmp(&b.key));
let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font_mut(font);
for GlyphRasterJob { key, result } in jobs {
let glyph_info = match result {
Err(_) => GlyphCacheEntry::Blank,
Ok(ref glyph) if glyph.width == 0 || glyph.height == 0 => {
GlyphCacheEntry::Blank
}
Ok(glyph) => {
let mut texture_cache_handle = TextureCacheHandle::invalid();
texture_cache.request(&texture_cache_handle, gpu_cache);
texture_cache.update(
&mut texture_cache_handle,
ImageDescriptor {
size: size2(glyph.width, glyph.height),
stride: None,
format: ImageFormat::BGRA8,
is_opaque: false,
allow_mipmaps: false,
offset: 0,
},
TextureFilter::Linear,
Some(CachedImageData::Raw(Arc::new(glyph.bytes))),
[glyph.left, -glyph.top, glyph.scale],
DirtyRect::All,
gpu_cache,
Some(glyph_key_cache.eviction_notice()),
UvRectKind::Rect,
Eviction::Auto,
);
GlyphCacheEntry::Cached(CachedGlyphInfo {
texture_cache_handle,
format: glyph.format,
})
}
};
glyph_key_cache.insert(key, glyph_info);
}
}
// Now that we are done with the critical path (rendering the glyphs),
// we can schedule removing the fonts if needed.
self.remove_dead_fonts();
}
}
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd)]
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -573,8 +750,6 @@ pub struct FontContexts {
// This worker should be accessed by threads that don't belong to the thread pool
// (in theory that's only the render backend thread so no contention expected either).
shared_context: Mutex<FontContext>,
#[cfg(feature = "pathfinder")]
pathfinder_context: Box<ThreadSafePathfinderFontContext>,
// Stored here as a convenience to get the current thread index.
#[allow(dead_code)]
workers: Arc<ThreadPool>,
@ -695,8 +870,6 @@ impl GlyphRasterizer {
let font_context = FontContexts {
worker_contexts: contexts,
shared_context: Mutex::new(shared_context),
#[cfg(feature = "pathfinder")]
pathfinder_context: create_pathfinder_font_context()?,
workers: Arc::clone(&workers),
locked_mutex: Mutex::new(false),
locked_cond: Condvar::new(),
@ -715,9 +888,6 @@ impl GlyphRasterizer {
}
pub fn add_font(&mut self, font_key: FontKey, template: FontTemplate) {
#[cfg(feature = "pathfinder")]
self.add_font_to_pathfinder(&font_key, &template);
self.font_contexts.async_for_each(move |mut context| {
context.add_font(&font_key, &template);
});

Просмотреть файл

@ -1,198 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
//! Module only available when pathfinder is deactivated when webrender is
//! compiled regularly (i.e. any configuration without feature = "pathfinder")
use api::{ImageDescriptor, ImageFormat, DirtyRect};
use crate::device::TextureFilter;
use euclid::size2;
use crate::gpu_types::UvRectKind;
use rayon::prelude::*;
use std::sync::{Arc, MutexGuard};
use crate::platform::font::FontContext;
use crate::glyph_rasterizer::{FontInstance, FontContexts, GlyphKey};
use crate::glyph_rasterizer::{GlyphRasterizer, GlyphRasterJob, GlyphRasterJobs};
use crate::glyph_cache::{GlyphCache, CachedGlyphInfo, GlyphCacheEntry};
use crate::resource_cache::CachedImageData;
use crate::texture_cache::{TextureCache, TextureCacheHandle, Eviction};
use crate::gpu_cache::GpuCache;
use crate::render_task::{RenderTaskGraph, RenderTaskCache};
use crate::profiler::TextureCacheProfileCounters;
impl FontContexts {
/// Get access to the font context associated to the current thread.
pub fn lock_current_context(&self) -> MutexGuard<FontContext> {
let id = self.current_worker_id();
self.lock_context(id)
}
pub(in super) fn current_worker_id(&self) -> Option<usize> {
self.workers.current_thread_index()
}
}
impl GlyphRasterizer {
pub fn request_glyphs(
&mut self,
glyph_cache: &mut GlyphCache,
font: FontInstance,
glyph_keys: &[GlyphKey],
texture_cache: &mut TextureCache,
gpu_cache: &mut GpuCache,
_: &mut RenderTaskCache,
_: &mut RenderTaskGraph,
) {
assert!(
self.font_contexts
.lock_shared_context()
.has_font(&font.font_key)
);
let mut new_glyphs = Vec::new();
let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font_mut(font.clone());
// select glyphs that have not been requested yet.
for key in glyph_keys {
if let Some(entry) = glyph_key_cache.try_get(key) {
match entry {
GlyphCacheEntry::Cached(ref glyph) => {
// Skip the glyph if it is already has a valid texture cache handle.
if !texture_cache.request(&glyph.texture_cache_handle, gpu_cache) {
continue;
}
// This case gets hit when we already rasterized the glyph, but the
// glyph has been evicted from the texture cache. Just force it to
// pending so it gets rematerialized.
}
// Otherwise, skip the entry if it is blank or pending.
GlyphCacheEntry::Blank | GlyphCacheEntry::Pending => continue,
}
}
new_glyphs.push(key.clone());
glyph_key_cache.add_glyph(key.clone(), GlyphCacheEntry::Pending);
}
if new_glyphs.is_empty() {
return;
}
self.pending_glyphs += 1;
self.request_glyphs_from_backend(font, new_glyphs);
}
pub(in super) fn request_glyphs_from_backend(&mut self, font: FontInstance, glyphs: Vec<GlyphKey>) {
let font_contexts = Arc::clone(&self.font_contexts);
let glyph_tx = self.glyph_tx.clone();
// spawn an async task to get off of the render backend thread as early as
// possible and in that task use rayon's fork join dispatch to rasterize the
// glyphs in the thread pool.
self.workers.spawn(move || {
let jobs = glyphs
.par_iter()
.map(|key: &GlyphKey| {
profile_scope!("glyph-raster");
let mut context = font_contexts.lock_current_context();
let mut job = GlyphRasterJob {
key: key.clone(),
result: context.rasterize_glyph(&font, key),
};
if let Ok(ref mut glyph) = job.result {
// Sanity check.
let bpp = 4; // We always render glyphs in 32 bits RGBA format.
assert_eq!(
glyph.bytes.len(),
bpp * (glyph.width * glyph.height) as usize
);
assert_eq!((glyph.left.fract(), glyph.top.fract()), (0.0, 0.0));
// Check if the glyph has a bitmap that needs to be downscaled.
glyph.downscale_bitmap_if_required(&font);
}
job
})
.collect();
glyph_tx.send(GlyphRasterJobs { font, jobs }).unwrap();
});
}
pub fn resolve_glyphs(
&mut self,
glyph_cache: &mut GlyphCache,
texture_cache: &mut TextureCache,
gpu_cache: &mut GpuCache,
_: &mut RenderTaskCache,
_: &mut RenderTaskGraph,
_: &mut TextureCacheProfileCounters,
) {
// Pull rasterized glyphs from the queue and update the caches.
while self.pending_glyphs > 0 {
self.pending_glyphs -= 1;
// TODO: rather than blocking until all pending glyphs are available
// we could try_recv and steal work from the thread pool to take advantage
// of the fact that this thread is alive and we avoid the added latency
// of blocking it.
let GlyphRasterJobs { font, mut jobs } = self.glyph_rx
.recv()
.expect("BUG: Should be glyphs pending!");
// Ensure that the glyphs are always processed in the same
// order for a given text run (since iterating a hash set doesn't
// guarantee order). This can show up as very small float inaccuracy
// differences in rasterizers due to the different coordinates
// that text runs get associated with by the texture cache allocator.
jobs.sort_by(|a, b| a.key.cmp(&b.key));
let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font_mut(font);
for GlyphRasterJob { key, result } in jobs {
let glyph_info = match result {
Err(_) => GlyphCacheEntry::Blank,
Ok(ref glyph) if glyph.width == 0 || glyph.height == 0 => {
GlyphCacheEntry::Blank
}
Ok(glyph) => {
let mut texture_cache_handle = TextureCacheHandle::invalid();
texture_cache.request(&texture_cache_handle, gpu_cache);
texture_cache.update(
&mut texture_cache_handle,
ImageDescriptor {
size: size2(glyph.width, glyph.height),
stride: None,
format: ImageFormat::BGRA8,
is_opaque: false,
allow_mipmaps: false,
offset: 0,
},
TextureFilter::Linear,
Some(CachedImageData::Raw(Arc::new(glyph.bytes))),
[glyph.left, -glyph.top, glyph.scale],
DirtyRect::All,
gpu_cache,
Some(glyph_key_cache.eviction_notice()),
UvRectKind::Rect,
Eviction::Auto,
);
GlyphCacheEntry::Cached(CachedGlyphInfo {
texture_cache_handle,
format: glyph.format,
})
}
};
glyph_key_cache.add_glyph(key, glyph_info);
}
}
// Now that we are done with the critical path (rendering the glyphs),
// we can schedule removing the fonts if needed.
self.remove_dead_fonts();
}
}

Просмотреть файл

@ -1,303 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
//! Module only available when pathfinder is activated
use api::{FontKey, FontTemplate, NativeFontHandle};
use api::units::{DeviceIntPoint, DeviceIntSize, DevicePixel};
use euclid::{TypedPoint2D, TypedSize2D, TypedVector2D};
use pathfinder_font_renderer;
use pathfinder_partitioner::mesh::Mesh as PathfinderMesh;
use pathfinder_path_utils::cubic_to_quadratic::CubicToQuadraticTransformer;
use crate::render_task::{RenderTask, RenderTaskGraph, RenderTaskCache, RenderTaskCacheKey,
RenderTaskCacheEntryHandle, RenderTaskCacheKeyKind, RenderTaskId,
RenderTaskLocation};
use crate::resource_cache::CacheItem;
use std::ops::Deref;
use std::sync::{Arc, Mutex, MutexGuard};
use crate::glyph_rasterizer::AddFont;
use crate::internal_types::ResourceCacheError;
use crate::glyph_cache::{GlyphCache, GlyphCacheEntry, CachedGlyphInfo};
use std::f32;
use crate::glyph_rasterizer::{FontInstance, GlyphRasterizer, GlyphFormat, GlyphKey, FontContexts};
use crate::texture_cache::TextureCache;
use crate::gpu_cache::GpuCache;
use crate::profiler::TextureCacheProfileCounters;
/// Should match macOS 10.13 High Sierra.
///
/// We multiply by sqrt(2) to compensate for the fact that dilation amounts are relative to the
/// pixel square on macOS and relative to the vertex normal in Pathfinder.
const STEM_DARKENING_FACTOR_X: f32 = 0.0121 * f32::consts::SQRT_2;
const STEM_DARKENING_FACTOR_Y: f32 = 0.0121 * 1.25 * f32::consts::SQRT_2;
/// Likewise, should match macOS 10.13 High Sierra.
const MAX_STEM_DARKENING_AMOUNT: f32 = 0.3 * f32::consts::SQRT_2;
const CUBIC_TO_QUADRATIC_APPROX_TOLERANCE: f32 = 0.01;
type PathfinderFontContext = pathfinder_font_renderer::FontContext<FontKey>;
impl AddFont for PathfinderFontContext {
fn add_font(&mut self, font_key: &FontKey, template: &FontTemplate) {
match *template {
FontTemplate::Raw(ref bytes, index) => {
drop(self.add_font_from_memory(&font_key, bytes.clone(), index))
}
FontTemplate::Native(ref native_font_handle) => {
drop(self.add_native_font(&font_key, NativeFontHandleWrapper(native_font_handle)))
}
}
}
}
pub(in super) fn create_pathfinder_font_context()
-> Result<Box<ThreadSafePathfinderFontContext>, ResourceCacheError>
{
match PathfinderFontContext::new() {
Ok(context) => Ok(Box::new(ThreadSafePathfinderFontContext(Mutex::new(context)))),
Err(_) => {
let msg = "Failed to create the Pathfinder font context!".to_owned();
Err(ResourceCacheError::new(msg))
}
}
}
pub struct ThreadSafePathfinderFontContext(Mutex<PathfinderFontContext>);
impl Deref for ThreadSafePathfinderFontContext {
type Target = Mutex<PathfinderFontContext>;
fn deref(&self) -> &Mutex<PathfinderFontContext> {
&self.0
}
}
/// PathfinderFontContext can contain a *mut IDWriteFactory.
/// However, since we know that it is wrapped in a Mutex, it is safe
/// to assume that this struct is thread-safe
unsafe impl Send for ThreadSafePathfinderFontContext {}
unsafe impl Sync for ThreadSafePathfinderFontContext { }
impl GlyphRasterizer {
pub(in super) fn add_font_to_pathfinder(&mut self, font_key: &FontKey, template: &FontTemplate) {
let font_contexts = Arc::clone(&self.font_contexts);
debug!("add_font_to_pathfinder({:?})", font_key);
font_contexts.lock_pathfinder_context().add_font(&font_key, &template);
}
pub fn get_cache_item_for_glyph(
&self,
glyph_key: &GlyphKey,
font: &FontInstance,
glyph_cache: &GlyphCache,
texture_cache: &TextureCache,
render_task_cache: &RenderTaskCache)
-> Option<(CacheItem, GlyphFormat)>
{
let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font(font);
let render_task_cache_key = match *glyph_key_cache.get(glyph_key) {
GlyphCacheEntry::Cached(ref cached_glyph) => {
(*cached_glyph).render_task_cache_key.clone()
}
GlyphCacheEntry::Blank => return None,
GlyphCacheEntry::Pending => {
panic!("GlyphRasterizer::get_cache_item_for_glyph(): Glyph should have been \
cached by now!")
}
};
let cache_item = render_task_cache.get_cache_item_for_render_task(texture_cache,
&render_task_cache_key);
Some((cache_item, font.get_glyph_format()))
}
pub(in super) fn request_glyph_from_pathfinder_if_necessary(
&mut self,
glyph_key: &GlyphKey,
font: &FontInstance,
scale: f32,
cached_glyph_info: CachedGlyphInfo,
texture_cache: &mut TextureCache,
gpu_cache: &mut GpuCache,
render_task_cache: &mut RenderTaskCache,
render_task_tree: &mut RenderTaskGraph,
) -> Result<(RenderTaskCacheEntryHandle,GlyphFormat), ()> {
let mut pathfinder_font_context = self.font_contexts.lock_pathfinder_context();
let render_task_cache_key = cached_glyph_info.render_task_cache_key;
let (glyph_origin, glyph_size) = (cached_glyph_info.origin, render_task_cache_key.size);
let user_data = [glyph_origin.x as f32, (glyph_origin.y - glyph_size.height) as f32, scale];
let handle = render_task_cache.request_render_task(render_task_cache_key,
texture_cache,
gpu_cache,
render_task_tree,
Some(user_data),
false,
|render_tasks| {
// TODO(pcwalton): Non-subpixel font render mode.
request_render_task_from_pathfinder(
glyph_key,
font,
scale,
&glyph_origin,
&glyph_size,
&mut *pathfinder_font_context,
render_tasks,
)
})?;
Ok((handle, font.get_glyph_format()))
}
pub fn request_glyphs(
&mut self,
glyph_cache: &mut GlyphCache,
font: FontInstance,
glyph_keys: &[GlyphKey],
texture_cache: &mut TextureCache,
gpu_cache: &mut GpuCache,
render_task_cache: &mut RenderTaskCache,
render_task_tree: &mut RenderTaskGraph,
) {
debug_assert!(self.font_contexts.lock_shared_context().has_font(&font.font_key));
let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font_mut(font.clone());
let (x_scale, y_scale) = font.transform.compute_scale().unwrap_or((1.0, 1.0));
let scale = font.oversized_scale_factor(x_scale, y_scale) as f32;
// select glyphs that have not been requested yet.
for glyph_key in glyph_keys {
let mut cached_glyph_info = None;
if let Some(GlyphCacheEntry::Cached(ref info)) = glyph_key_cache.try_get(glyph_key) {
cached_glyph_info = Some(info.clone());
} else {
let pathfinder_font_context = self.font_contexts.lock_pathfinder_context();
let pathfinder_font_instance = pathfinder_font_renderer::FontInstance {
font_key: font.font_key.clone(),
size: font.size.scale_by(scale.recip()),
};
// TODO: pathfinder will need to support 2D subpixel offset
let pathfinder_subpixel_offset =
pathfinder_font_renderer::SubpixelOffset(glyph_key.subpixel_offset().0 as u8);
let pathfinder_glyph_key =
pathfinder_font_renderer::GlyphKey::new(glyph_key.index(),
pathfinder_subpixel_offset);
if let Ok(glyph_dimensions) =
pathfinder_font_context.glyph_dimensions(&pathfinder_font_instance,
&pathfinder_glyph_key,
false) {
let render_task_cache_key = RenderTaskCacheKey {
size: TypedSize2D::from_untyped(&glyph_dimensions.size.to_i32()),
kind: RenderTaskCacheKeyKind::Glyph(self.next_gpu_glyph_cache_key),
};
cached_glyph_info = Some(CachedGlyphInfo {
render_task_cache_key,
format: font.get_glyph_format(),
origin: DeviceIntPoint::new(glyph_dimensions.origin.x as i32,
-glyph_dimensions.origin.y as i32),
});
self.next_gpu_glyph_cache_key.0 += 1;
}
}
let handle = match cached_glyph_info {
Some(glyph_info) => {
match self.request_glyph_from_pathfinder_if_necessary(
glyph_key,
&font,
scale,
glyph_info.clone(),
texture_cache,
gpu_cache,
render_task_cache,
render_task_tree,
) {
Ok(_) => GlyphCacheEntry::Cached(glyph_info),
Err(_) => GlyphCacheEntry::Blank,
}
}
None => GlyphCacheEntry::Blank,
};
glyph_key_cache.add_glyph(glyph_key.clone(), handle);
}
}
pub fn resolve_glyphs(
&mut self,
_: &mut GlyphCache,
_: &mut TextureCache,
_: &mut GpuCache,
_: &mut RenderTaskCache,
_: &mut RenderTaskGraph,
_: &mut TextureCacheProfileCounters,
) {
self.remove_dead_fonts();
}
}
impl FontContexts {
pub fn lock_pathfinder_context(&self) -> MutexGuard<PathfinderFontContext> {
self.pathfinder_context.lock().unwrap()
}
}
fn compute_embolden_amount(ppem: f32) -> TypedVector2D<f32, DevicePixel> {
TypedVector2D::new(f32::min(ppem * STEM_DARKENING_FACTOR_X, MAX_STEM_DARKENING_AMOUNT),
f32::min(ppem * STEM_DARKENING_FACTOR_Y, MAX_STEM_DARKENING_AMOUNT))
}
fn request_render_task_from_pathfinder(
glyph_key: &GlyphKey,
font: &FontInstance,
scale: f32,
glyph_origin: &DeviceIntPoint,
glyph_size: &DeviceIntSize,
font_context: &mut PathfinderFontContext,
render_tasks: &mut RenderTaskGraph,
) -> Result<RenderTaskId, ()> {
let size = font.size.scale_by(scale.recip());
let pathfinder_font_instance = pathfinder_font_renderer::FontInstance {
font_key: font.font_key.clone(),
size,
};
// TODO: pathfinder will need to support 2D subpixel offset
let pathfinder_subpixel_offset =
pathfinder_font_renderer::SubpixelOffset(glyph_key.subpixel_offset().0 as u8);
let glyph_subpixel_offset: f64 = glyph_key.subpixel_offset().0.into();
let pathfinder_glyph_key = pathfinder_font_renderer::GlyphKey::new(glyph_key.index(),
pathfinder_subpixel_offset);
// TODO(pcwalton): Fall back to CPU rendering if Pathfinder fails to collect the outline.
let mut mesh = PathfinderMesh::new();
let outline = font_context.glyph_outline(&pathfinder_font_instance,
&pathfinder_glyph_key)?;
let tolerance = CUBIC_TO_QUADRATIC_APPROX_TOLERANCE;
mesh.push_stencil_segments(CubicToQuadraticTransformer::new(outline.iter(), tolerance));
mesh.push_stencil_normals(CubicToQuadraticTransformer::new(outline.iter(), tolerance));
// FIXME(pcwalton): Support vertical subpixel offsets.
// FIXME(pcwalton): Embolden amount should be 0 on macOS if "Use LCD font
// smoothing" is unchecked in System Preferences.
let subpixel_offset = TypedPoint2D::new(glyph_subpixel_offset as f32, 0.0);
let embolden_amount = compute_embolden_amount(size.to_f32_px());
let location = RenderTaskLocation::Dynamic(None, *glyph_size);
let glyph_render_task = RenderTask::new_glyph(
location.clone(),
mesh,
&glyph_origin,
&subpixel_offset,
font.render_mode,
&embolden_amount,
);
Ok(render_tasks.add(glyph_render_task))
}
pub struct NativeFontHandleWrapper<'a>(pub &'a NativeFontHandle);

Просмотреть файл

@ -1,297 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
//! GPU glyph rasterization using Pathfinder.
use crate::api::{ImageFormat, FontRenderMode, TextureTarget};
use crate::api::units::*;
use crate::debug_colors;
use crate::device::{DrawTarget, Device, Texture, TextureFilter, VAO};
use euclid::{Point2D, Size2D, Transform3D, TypedVector2D, Vector2D};
use crate::internal_types::RenderTargetInfo;
use pathfinder_gfx_utils::ShelfBinPacker;
use crate::profiler::GpuProfileTag;
use crate::renderer::{self, ImageBufferKind, Renderer, RendererError, RendererStats};
use crate::renderer::{TextureSampler, VertexArrayKind, ShaderPrecacheFlags};
use crate::shade::{LazilyCompiledShader, ShaderKind};
use crate::tiling::GlyphJob;
// The area lookup table in uncompressed grayscale TGA format (TGA image format 3).
static AREA_LUT_TGA_BYTES: &'static [u8] = include_bytes!("../res/area-lut.tga");
const HORIZONTAL_BIN_PADDING: i32 = 3;
const GPU_TAG_GLYPH_STENCIL: GpuProfileTag = GpuProfileTag {
label: "Glyph Stencil",
color: debug_colors::STEELBLUE,
};
const GPU_TAG_GLYPH_COVER: GpuProfileTag = GpuProfileTag {
label: "Glyph Cover",
color: debug_colors::LIGHTSTEELBLUE,
};
pub struct GpuGlyphRenderer {
pub area_lut_texture: Texture,
pub vector_stencil_vao: VAO,
pub vector_cover_vao: VAO,
// These are Pathfinder shaders, used for rendering vector graphics.
vector_stencil: LazilyCompiledShader,
vector_cover: LazilyCompiledShader,
}
impl GpuGlyphRenderer {
pub fn new(device: &mut Device, prim_vao: &VAO, precache_flags: ShaderPrecacheFlags)
-> Result<GpuGlyphRenderer, RendererError> {
// Make sure the area LUT is uncompressed grayscale TGA, 8bpp.
debug_assert!(AREA_LUT_TGA_BYTES[2] == 3);
debug_assert!(AREA_LUT_TGA_BYTES[16] == 8);
let area_lut_width = (AREA_LUT_TGA_BYTES[12] as u32) |
((AREA_LUT_TGA_BYTES[13] as u32) << 8);
let area_lut_height = (AREA_LUT_TGA_BYTES[14] as u32) |
((AREA_LUT_TGA_BYTES[15] as u32) << 8);
let area_lut_pixels =
&AREA_LUT_TGA_BYTES[18..(18 + area_lut_width * area_lut_height) as usize];
let area_lut_texture = device.create_texture(
TextureTarget::Default,
ImageFormat::R8,
area_lut_width as i32,
area_lut_height as i32,
TextureFilter::Linear,
None,
1,
);
device.upload_texture_immediate(&area_lut_texture, area_lut_pixels);
let vector_stencil_vao =
device.create_vao_with_new_instances(&renderer::desc::VECTOR_STENCIL, prim_vao);
let vector_cover_vao = device.create_vao_with_new_instances(&renderer::desc::VECTOR_COVER,
prim_vao);
// Load Pathfinder vector graphics shaders.
let vector_stencil =
LazilyCompiledShader::new(ShaderKind::VectorStencil,
"pf_vector_stencil",
&[ImageBufferKind::Texture2D.get_feature_string()],
device,
precache_flags)?;
let vector_cover =
LazilyCompiledShader::new(ShaderKind::VectorCover,
"pf_vector_cover",
&[ImageBufferKind::Texture2D.get_feature_string()],
device,
precache_flags)?;
Ok(GpuGlyphRenderer {
area_lut_texture,
vector_stencil_vao,
vector_cover_vao,
vector_stencil,
vector_cover,
})
}
}
impl Renderer {
/// Renders glyphs using the vector graphics shaders (Pathfinder).
pub fn stencil_glyphs(&mut self,
glyphs: &[GlyphJob],
projection: &Transform3D<f32>,
target_size: &DeviceIntSize,
stats: &mut RendererStats)
-> Option<StenciledGlyphPage> {
if glyphs.is_empty() {
return None
}
let _timer = self.gpu_profile.start_timer(GPU_TAG_GLYPH_STENCIL);
let texture = self.device.create_texture(
TextureTarget::Default,
ImageFormat::RGBAF32,
target_size.width,
target_size.height,
TextureFilter::Nearest,
Some(RenderTargetInfo {
has_depth: false,
}),
1,
);
// Initialize temporary framebuffer.
// FIXME(pcwalton): Cache this!
// FIXME(pcwalton): Use RF32, not RGBAF32!
let mut current_page = StenciledGlyphPage {
texture,
glyphs: vec![],
};
// Allocate all target rects.
let mut packer = ShelfBinPacker::new(&target_size.to_i32().to_untyped(),
&Vector2D::new(HORIZONTAL_BIN_PADDING, 0));
let mut glyph_indices: Vec<_> = (0..(glyphs.len())).collect();
glyph_indices.sort_by(|&a, &b| {
glyphs[b].target_rect.size.height.cmp(&glyphs[a].target_rect.size.height)
});
for &glyph_index in &glyph_indices {
let glyph = &glyphs[glyph_index];
let x_scale = x_scale_for_render_mode(glyph.render_mode);
let stencil_size = Size2D::new(glyph.target_rect.size.width * x_scale,
glyph.target_rect.size.height);
match packer.add(&stencil_size) {
Err(_) => return None,
Ok(origin) => {
current_page.glyphs.push(VectorCoverInstanceAttrs {
target_rect: glyph.target_rect,
stencil_origin: DeviceIntPoint::from_untyped(&origin),
subpixel: (glyph.render_mode == FontRenderMode::Subpixel) as u16,
})
}
}
}
// Initialize path info.
let mut path_info_texels = Vec::with_capacity(glyphs.len() * 12);
for (stenciled_glyph_index, &glyph_index) in glyph_indices.iter().enumerate() {
let glyph = &glyphs[glyph_index];
let stenciled_glyph = &current_page.glyphs[stenciled_glyph_index];
let x_scale = x_scale_for_render_mode(glyph.render_mode) as f32;
let glyph_origin = TypedVector2D::new(-glyph.origin.x as f32 * x_scale,
-glyph.origin.y as f32);
let subpixel_offset = TypedVector2D::new(glyph.subpixel_offset.x * x_scale,
glyph.subpixel_offset.y);
let rect = stenciled_glyph.stencil_rect()
.to_f32()
.translate(&glyph_origin)
.translate(&subpixel_offset);
path_info_texels.extend_from_slice(&[
x_scale, 0.0, 0.0, -1.0,
rect.origin.x, rect.max_y(), 0.0, 0.0,
rect.size.width, rect.size.height,
glyph.embolden_amount.x,
glyph.embolden_amount.y,
]);
}
// TODO(pcwalton): Cache this texture!
let path_info_texture = self.device.create_texture(
TextureTarget::Default,
ImageFormat::RGBAF32,
3,
glyphs.len() as i32,
TextureFilter::Nearest,
None,
1,
);
self.device.upload_texture_immediate(&path_info_texture, &path_info_texels);
self.gpu_glyph_renderer.vector_stencil.bind(&mut self.device,
projection,
&mut self.renderer_errors);
self.device.bind_draw_target(DrawTarget::from_texture(
&current_page.texture,
0,
false,
));
self.device.clear_target(Some([0.0, 0.0, 0.0, 0.0]), None, None);
self.device.set_blend(true);
self.device.set_blend_mode_subpixel_pass1();
let mut instance_data = vec![];
for (path_id, &glyph_id) in glyph_indices.iter().enumerate() {
let glyph = &glyphs[glyph_id];
instance_data.extend(glyph.mesh
.stencil_segments
.iter()
.zip(glyph.mesh.stencil_normals.iter())
.map(|(segment, normals)| {
VectorStencilInstanceAttrs {
from_position: segment.from,
ctrl_position: segment.ctrl,
to_position: segment.to,
from_normal: normals.from,
ctrl_normal: normals.ctrl,
to_normal: normals.to,
path_id: path_id as u16,
}
}));
}
self.device.bind_texture(TextureSampler::color(0),
&self.gpu_glyph_renderer.area_lut_texture);
self.device.bind_texture(TextureSampler::color(1), &path_info_texture);
self.draw_instanced_batch_with_previously_bound_textures(&instance_data,
VertexArrayKind::VectorStencil,
stats);
self.device.delete_texture(path_info_texture);
Some(current_page)
}
/// Blits glyphs from the stencil texture to the texture cache.
///
/// Deletes the stencil texture at the end.
/// FIXME(pcwalton): This is bad. Cache it somehow.
pub fn cover_glyphs(&mut self,
stencil_page: StenciledGlyphPage,
projection: &Transform3D<f32>,
stats: &mut RendererStats) {
debug_assert!(!stencil_page.glyphs.is_empty());
let _timer = self.gpu_profile.start_timer(GPU_TAG_GLYPH_COVER);
self.gpu_glyph_renderer.vector_cover.bind(&mut self.device,
projection,
&mut self.renderer_errors);
self.device.bind_texture(TextureSampler::color(0), &stencil_page.texture);
self.draw_instanced_batch_with_previously_bound_textures(&stencil_page.glyphs,
VertexArrayKind::VectorCover,
stats);
self.device.delete_texture(stencil_page.texture);
}
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
struct VectorStencilInstanceAttrs {
from_position: Point2D<f32>,
ctrl_position: Point2D<f32>,
to_position: Point2D<f32>,
from_normal: Vector2D<f32>,
ctrl_normal: Vector2D<f32>,
to_normal: Vector2D<f32>,
path_id: u16,
}
pub struct StenciledGlyphPage {
texture: Texture,
glyphs: Vec<VectorCoverInstanceAttrs>,
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
struct VectorCoverInstanceAttrs {
target_rect: DeviceIntRect,
stencil_origin: DeviceIntPoint,
subpixel: u16,
}
impl VectorCoverInstanceAttrs {
fn stencil_rect(&self) -> DeviceIntRect {
DeviceIntRect::new(self.stencil_origin, self.target_rect.size)
}
}
fn x_scale_for_render_mode(render_mode: FontRenderMode) -> i32 {
match render_mode {
FontRenderMode::Subpixel => 3,
FontRenderMode::Mono | FontRenderMode::Alpha => 1,
}
}

Просмотреть файл

@ -98,8 +98,6 @@ mod gamma_lut;
mod glyph_cache;
mod glyph_rasterizer;
mod gpu_cache;
#[cfg(feature = "pathfinder")]
mod gpu_glyph_renderer;
mod gpu_types;
mod hit_test;
mod image;
@ -174,14 +172,6 @@ pub extern crate euclid;
extern crate fxhash;
extern crate gleam;
extern crate num_traits;
#[cfg(feature = "pathfinder")]
extern crate pathfinder_font_renderer;
#[cfg(feature = "pathfinder")]
extern crate pathfinder_gfx_utils;
#[cfg(feature = "pathfinder")]
extern crate pathfinder_partitioner;
#[cfg(feature = "pathfinder")]
extern crate pathfinder_path_utils;
extern crate plane_split;
extern crate rayon;
#[cfg(feature = "ron")]

Просмотреть файл

@ -14,12 +14,10 @@ use core_graphics::base::{kCGImageAlphaNoneSkipFirst, kCGImageAlphaPremultiplied
use core_graphics::base::{kCGBitmapByteOrder32Little};
use core_graphics::color_space::CGColorSpace;
use core_graphics::context::CGContext;
#[cfg(not(feature = "pathfinder"))]
use core_graphics::context::{CGBlendMode, CGTextDrawingMode};
use core_graphics::data_provider::CGDataProvider;
use core_graphics::font::{CGFont, CGGlyph};
use core_graphics::geometry::{CGAffineTransform, CGPoint, CGSize};
#[cfg(not(feature = "pathfinder"))]
use core_graphics::geometry::{CG_AFFINE_TRANSFORM_IDENTITY, CGRect};
use core_text;
use core_text::font::{CTFont, CTFontRef};
@ -27,9 +25,6 @@ use core_text::font_descriptor::{kCTFontDefaultOrientation, kCTFontColorGlyphsTr
use euclid::Size2D;
use crate::gamma_lut::{ColorLut, GammaLut};
use crate::glyph_rasterizer::{FontInstance, FontTransform, GlyphKey};
#[cfg(feature = "pathfinder")]
use crate::glyph_rasterizer::NativeFontHandleWrapper;
#[cfg(not(feature = "pathfinder"))]
use crate::glyph_rasterizer::{GlyphFormat, GlyphRasterError, GlyphRasterResult, RasterizedGlyph};
use crate::internal_types::{FastHashMap, ResourceCacheError};
use std::collections::hash_map::Entry;
@ -427,7 +422,6 @@ impl FontContext {
}
// Assumes the pixels here are linear values from CG
#[cfg(not(feature = "pathfinder"))]
fn gamma_correct_pixels(
&self,
pixels: &mut Vec<u8>,
@ -495,7 +489,6 @@ impl FontContext {
}
}
#[cfg(not(feature = "pathfinder"))]
pub fn rasterize_glyph(&mut self, font: &FontInstance, key: &GlyphKey) -> GlyphRasterResult {
let (x_scale, y_scale) = font.transform.compute_scale().unwrap_or((1.0, 1.0));
let scale = font.oversized_scale_factor(x_scale, y_scale);
@ -738,13 +731,6 @@ impl FontContext {
}
}
#[cfg(feature = "pathfinder")]
impl<'a> Into<CGFont> for NativeFontHandleWrapper<'a> {
fn into(self) -> CGFont {
(self.0).0.clone()
}
}
// Avoids taking locks by recycling Core Graphics contexts.
#[allow(dead_code)]
struct GraphicsContext {

Просмотреть файл

@ -22,14 +22,10 @@ use freetype::freetype::{FT_FACE_FLAG_MULTIPLE_MASTERS};
use freetype::succeeded;
use crate::glyph_rasterizer::{FontInstance, GlyphFormat, GlyphKey};
use crate::glyph_rasterizer::{GlyphRasterError, GlyphRasterResult, RasterizedGlyph};
#[cfg(feature = "pathfinder")]
use crate::glyph_rasterizer::NativeFontHandleWrapper;
use crate::internal_types::{FastHashMap, ResourceCacheError};
#[cfg(any(not(target_os = "android"), feature = "no_static_freetype"))]
use libc::{dlsym, RTLD_DEFAULT};
use libc::free;
#[cfg(feature = "pathfinder")]
use pathfinder_font_renderer::freetype as pf_freetype;
use std::{cmp, mem, ptr, slice};
use std::cmp::max;
use std::collections::hash_map::Entry;
@ -770,7 +766,6 @@ impl FontContext {
}
}
#[cfg(not(feature = "pathfinder"))]
pub fn rasterize_glyph(&mut self, font: &FontInstance, key: &GlyphKey) -> GlyphRasterResult {
let (slot, scale) = self.load_glyph(font, key).ok_or(GlyphRasterError::LoadFailed)?;
@ -977,12 +972,3 @@ impl Drop for FontContext {
}
}
}
#[cfg(feature = "pathfinder")]
impl<'a> Into<pf_freetype::FontDescriptor> for NativeFontHandleWrapper<'a> {
fn into(self) -> pf_freetype::FontDescriptor {
let NativeFontHandleWrapper(font_handle) = self;
let str = font_handle.path.as_os_str().to_str().unwrap();
pf_freetype::FontDescriptor::new(str.into(), font_handle.index)
}
}

Просмотреть файл

@ -8,23 +8,15 @@ use dwrote;
use crate::gamma_lut::ColorLut;
use crate::glyph_rasterizer::{FontInstance, FontTransform, GlyphKey};
use crate::internal_types::{FastHashMap, FastHashSet, ResourceCacheError};
use crate::glyph_rasterizer::{GlyphFormat, GlyphRasterError, GlyphRasterResult, RasterizedGlyph};
use crate::gamma_lut::GammaLut;
use std::borrow::Borrow;
use std::collections::hash_map::Entry;
use std::hash::{Hash, Hasher};
use std::path::Path;
use std::sync::{Arc, Mutex};
cfg_if! {
if #[cfg(feature = "pathfinder")] {
use pathfinder_font_renderer::{PathfinderComPtr, IDWriteFontFace};
use crate::glyph_rasterizer::NativeFontHandleWrapper;
} else if #[cfg(not(feature = "pathfinder"))] {
use api::FontInstancePlatformOptions;
use crate::glyph_rasterizer::{GlyphFormat, GlyphRasterError, GlyphRasterResult, RasterizedGlyph};
use crate::gamma_lut::GammaLut;
use std::mem;
}
}
use api::FontInstancePlatformOptions;
use std::mem;
lazy_static! {
static ref DEFAULT_FONT_DESCRIPTOR: dwrote::FontDescriptor = dwrote::FontDescriptor {
@ -80,7 +72,6 @@ struct FontFace {
pub struct FontContext {
fonts: FastHashMap<FontKey, FontFace>,
variations: FastHashMap<(FontKey, dwrote::DWRITE_FONT_SIMULATIONS, Vec<FontVariation>), dwrote::FontFace>,
#[cfg(not(feature = "pathfinder"))]
gamma_luts: FastHashMap<(u16, u16), GammaLut>,
}
@ -148,7 +139,6 @@ impl FontContext {
Ok(FontContext {
fonts: FastHashMap::default(),
variations: FastHashMap::default(),
#[cfg(not(feature = "pathfinder"))]
gamma_luts: FastHashMap::default(),
})
}
@ -442,7 +432,6 @@ impl FontContext {
}
// DWrite ClearType gives us values in RGB, but WR expects BGRA.
#[cfg(not(feature = "pathfinder"))]
fn convert_to_bgra(
&self,
pixels: &[u8],
@ -511,7 +500,6 @@ impl FontContext {
}
}
#[cfg(not(feature = "pathfinder"))]
pub fn rasterize_glyph(&mut self, font: &FontInstance, key: &GlyphKey) -> GlyphRasterResult {
let (x_scale, y_scale) = font.transform.compute_scale().unwrap_or((1.0, 1.0));
let scale = font.oversized_scale_factor(x_scale, y_scale);
@ -605,16 +593,3 @@ impl FontContext {
})
}
}
#[cfg(feature = "pathfinder")]
impl<'a> From<NativeFontHandleWrapper<'a>> for PathfinderComPtr<IDWriteFontFace> {
fn from(font_handle: NativeFontHandleWrapper<'a>) -> Self {
if let Some(file) = dwrote::FontFile::new_from_path(&font_handle.0.path) {
let index = font_handle.0.index;
if let Ok(face) = file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE) {
return unsafe { PathfinderComPtr::new(face.as_ptr()) };
}
}
panic!("missing font {:?}", font_handle.0)
}
}

Просмотреть файл

@ -5,24 +5,17 @@
use api::{ImageDescriptor, ImageFormat, FilterPrimitive, FilterPrimitiveInput, FilterPrimitiveKind};
use api::{LineStyle, LineOrientation, ClipMode, DirtyRect, MixBlendMode, ColorF, ColorSpace};
use api::units::*;
#[cfg(feature = "pathfinder")]
use api::FontRenderMode;
use crate::border::BorderSegmentCacheKey;
use crate::box_shadow::{BoxShadowCacheKey};
use crate::clip::{ClipDataStore, ClipItem, ClipStore, ClipNodeRange, ClipNodeFlags};
use crate::clip_scroll_tree::SpatialNodeIndex;
use crate::device::TextureFilter;
#[cfg(feature = "pathfinder")]
use euclid::{TypedPoint2D, TypedVector2D};
use crate::filterdata::SFilterData;
use crate::frame_builder::FrameBuilderConfig;
use crate::freelist::{FreeList, FreeListHandle, WeakFreeListHandle};
use crate::glyph_rasterizer::GpuGlyphCacheKey;
use crate::gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle};
use crate::gpu_types::{BorderInstance, ImageSource, UvRectKind, SnapOffsets};
use crate::internal_types::{CacheTextureId, FastHashMap, LayerIndex, SavedTargetIndex, TextureSource};
#[cfg(feature = "pathfinder")]
use pathfinder_partitioner::mesh::Mesh;
use crate::prim_store::{PictureIndex, PrimitiveVisibilityMask};
use crate::prim_store::image::ImageCacheKey;
use crate::prim_store::gradient::{GRADIENT_FP_STOPS, GradientCacheKey, GradientStopKey};
@ -549,25 +542,6 @@ pub struct ScalingTask {
uv_rect_kind: UvRectKind,
}
#[derive(Debug)]
#[cfg(feature = "pathfinder")]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct GlyphTask {
/// After job building, this becomes `None`.
pub mesh: Option<Mesh>,
pub origin: DeviceIntPoint,
pub subpixel_offset: TypedPoint2D<f32, DevicePixel>,
pub render_mode: FontRenderMode,
pub embolden_amount: TypedVector2D<f32, DevicePixel>,
}
#[cfg(not(feature = "pathfinder"))]
#[derive(Debug)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct GlyphTask;
// Where the source data for a blit task can be found.
#[derive(Debug)]
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -658,8 +632,6 @@ pub enum RenderTaskKind {
ClipRegion(ClipRegionTask),
VerticalBlur(BlurTask),
HorizontalBlur(BlurTask),
#[allow(dead_code)]
Glyph(GlyphTask),
Readback(DeviceIntRect),
Scaling(ScalingTask),
Blit(BlitTask),
@ -679,7 +651,6 @@ impl RenderTaskKind {
RenderTaskKind::ClipRegion(..) => "ClipRegion",
RenderTaskKind::VerticalBlur(..) => "VerticalBlur",
RenderTaskKind::HorizontalBlur(..) => "HorizontalBlur",
RenderTaskKind::Glyph(..) => "Glyph",
RenderTaskKind::Readback(..) => "Readback",
RenderTaskKind::Scaling(..) => "Scaling",
RenderTaskKind::Blit(..) => "Blit",
@ -1481,30 +1452,6 @@ impl RenderTask {
)
}
#[cfg(feature = "pathfinder")]
pub fn new_glyph(
location: RenderTaskLocation,
mesh: Mesh,
origin: &DeviceIntPoint,
subpixel_offset: &TypedPoint2D<f32, DevicePixel>,
render_mode: FontRenderMode,
embolden_amount: &TypedVector2D<f32, DevicePixel>,
) -> Self {
RenderTask {
children: vec![],
location,
kind: RenderTaskKind::Glyph(GlyphTask {
mesh: Some(mesh),
origin: *origin,
subpixel_offset: *subpixel_offset,
render_mode,
embolden_amount: *embolden_amount,
}),
clear_mode: ClearMode::Transparent,
saved_index: None,
}
}
fn uv_rect_kind(&self) -> UvRectKind {
match self.kind {
RenderTaskKind::CacheMask(..) |
@ -1530,7 +1477,6 @@ impl RenderTask {
}
RenderTaskKind::ClipRegion(..) |
RenderTaskKind::Glyph(_) |
RenderTaskKind::Border(..) |
RenderTaskKind::Gradient(..) |
RenderTaskKind::LineDecoration(..) |
@ -1588,9 +1534,6 @@ impl RenderTask {
0.0,
]
}
RenderTaskKind::Glyph(_) => {
[0.0, 1.0, 0.0]
}
RenderTaskKind::Readback(..) |
RenderTaskKind::Scaling(..) |
RenderTaskKind::Border(..) |
@ -1656,8 +1599,7 @@ impl RenderTask {
RenderTaskKind::Border(..) |
RenderTaskKind::CacheMask(..) |
RenderTaskKind::Gradient(..) |
RenderTaskKind::LineDecoration(..) |
RenderTaskKind::Glyph(..) => {
RenderTaskKind::LineDecoration(..) => {
panic!("texture handle not supported for this task kind");
}
#[cfg(test)]
@ -1720,7 +1662,6 @@ impl RenderTask {
match self.kind {
RenderTaskKind::LineDecoration(..) |
RenderTaskKind::Readback(..) |
RenderTaskKind::Glyph(..) |
RenderTaskKind::Border(..) |
RenderTaskKind::Gradient(..) |
RenderTaskKind::Picture(..) |
@ -1772,8 +1713,7 @@ impl RenderTask {
RenderTaskKind::Border(..) |
RenderTaskKind::CacheMask(..) |
RenderTaskKind::Gradient(..) |
RenderTaskKind::LineDecoration(..) |
RenderTaskKind::Glyph(..) => {
RenderTaskKind::LineDecoration(..) => {
return;
}
#[cfg(test)]
@ -1862,9 +1802,6 @@ impl RenderTask {
pt.new_level("Blit".to_owned());
pt.add_item(format!("source: {:?}", task.source));
}
RenderTaskKind::Glyph(..) => {
pt.new_level("Glyph".to_owned());
}
RenderTaskKind::Gradient(..) => {
pt.new_level("Gradient".to_owned());
}
@ -1912,8 +1849,6 @@ impl RenderTask {
pub enum RenderTaskCacheKeyKind {
BoxShadow(BoxShadowCacheKey),
Image(ImageCacheKey),
#[allow(dead_code)]
Glyph(GpuGlyphCacheKey),
BorderSegment(BorderSegmentCacheKey),
LineDecoration(LineDecorationCacheKey),
Gradient(GradientCacheKey),

Просмотреть файл

@ -62,8 +62,6 @@ use crate::glyph_cache::GlyphCache;
use crate::glyph_rasterizer::{GlyphFormat, GlyphRasterizer};
use crate::gpu_cache::{GpuBlockData, GpuCacheUpdate, GpuCacheUpdateList};
use crate::gpu_cache::{GpuCacheDebugChunk, GpuCacheDebugCmd};
#[cfg(feature = "pathfinder")]
use crate::gpu_glyph_renderer::GpuGlyphRenderer;
use crate::gpu_types::{PrimitiveHeaderI, PrimitiveHeaderF, ScalingInstance, SvgFilterInstance, TransformData, ResolveInstanceData};
use crate::internal_types::{TextureSource, ORTHO_FAR_PLANE, ORTHO_NEAR_PLANE, ResourceCacheError};
use crate::internal_types::{CacheTextureId, DebugOutput, FastHashMap, FastHashSet, LayerIndex, RenderedDocument, ResultMsg};
@ -107,8 +105,6 @@ use thread_profiler::{register_thread_with_profiler, write_profile};
use crate::tiling::{AlphaRenderTarget, ColorRenderTarget, PictureCacheTarget};
use crate::tiling::{BlitJob, BlitJobSource, RenderPassKind, RenderTargetList};
use crate::tiling::{Frame, RenderTarget, RenderTargetKind, TextureCacheRenderTarget};
#[cfg(not(feature = "pathfinder"))]
use crate::tiling::GlyphJob;
use time::precise_time_ns;
cfg_if! {
@ -897,19 +893,6 @@ impl CpuProfile {
}
}
#[cfg(not(feature = "pathfinder"))]
pub struct GpuGlyphRenderer;
#[cfg(not(feature = "pathfinder"))]
impl GpuGlyphRenderer {
fn new(_: &mut Device, _: &VAO, _: ShaderPrecacheFlags) -> Result<GpuGlyphRenderer, RendererError> {
Ok(GpuGlyphRenderer)
}
}
#[cfg(not(feature = "pathfinder"))]
struct StenciledGlyphPage;
/// A Texture that has been initialized by the `device` module and is ready to
/// be used.
struct ActiveTexture {
@ -1683,8 +1666,6 @@ pub struct Renderer {
shaders: Rc<RefCell<Shaders>>,
pub gpu_glyph_renderer: GpuGlyphRenderer,
max_recorded_profiles: usize,
clear_color: Option<ColorF>,
@ -1999,10 +1980,6 @@ impl Renderer {
device.update_vao_indices(&prim_vao, &quad_indices, VertexUsageHint::Static);
device.update_vao_main_vertices(&prim_vao, &quad_vertices, VertexUsageHint::Static);
let gpu_glyph_renderer = r#try!(GpuGlyphRenderer::new(&mut device,
&prim_vao,
options.precache_flags));
let blur_vao = device.create_vao_with_new_instances(&desc::BLUR, &prim_vao);
let clip_vao = device.create_vao_with_new_instances(&desc::CLIP, &prim_vao);
let border_vao = device.create_vao_with_new_instances(&desc::BORDER, &prim_vao);
@ -2235,7 +2212,6 @@ impl Renderer {
enable_advanced_blend_barriers: !ext_blend_equation_advanced_coherent,
last_time: 0,
gpu_profile,
gpu_glyph_renderer,
vaos: RendererVAOs {
prim_vao,
blur_vao,
@ -3274,7 +3250,7 @@ impl Renderer {
// the batch.
debug_assert!(!data.is_empty());
let vao = get_vao(vertex_array_kind, &self.vaos, &self.gpu_glyph_renderer);
let vao = get_vao(vertex_array_kind, &self.vaos);
self.device.bind_vao(vao);
@ -4112,20 +4088,20 @@ impl Renderer {
stats: &mut RendererStats,
) {
let texture_source = TextureSource::TextureCache(*texture);
let (target_size, projection) = {
let projection = {
let texture = self.texture_resolver
.resolve(&texture_source)
.expect("BUG: invalid target texture");
let target_size = texture.get_dimensions();
let projection = Transform3D::ortho(
Transform3D::ortho(
0.0,
target_size.width as f32,
0.0,
target_size.height as f32,
ORTHO_NEAR_PLANE,
ORTHO_FAR_PLANE,
);
(target_size, projection)
)
};
self.device.disable_depth();
@ -4133,9 +4109,6 @@ impl Renderer {
self.set_blend(false, FramebufferKind::Other);
// Handle any Pathfinder glyphs.
let stencil_page = self.stencil_glyphs(&target.glyphs, &projection, &target_size, stats);
{
let texture = self.texture_resolver
.resolve(&texture_source)
@ -4270,29 +4243,8 @@ impl Renderer {
stats,
);
}
// Blit any Pathfinder glyphs to the cache texture.
if let Some(stencil_page) = stencil_page {
self.cover_glyphs(stencil_page, &projection, stats);
}
}
#[cfg(not(feature = "pathfinder"))]
fn stencil_glyphs(&mut self,
_: &[GlyphJob],
_: &Transform3D<f32>,
_: &DeviceIntSize,
_: &mut RendererStats)
-> Option<StenciledGlyphPage> {
None
}
#[cfg(not(feature = "pathfinder"))]
fn cover_glyphs(&mut self,
_: StenciledGlyphPage,
_: &Transform3D<f32>,
_: &mut RendererStats) {}
fn update_deferred_resolves(&mut self, deferred_resolves: &[DeferredResolve]) -> Option<GpuCacheUpdateList> {
// The first thing we do is run through any pending deferred
// resolves, and use a callback to get the UV rect for this
@ -6042,30 +5994,8 @@ impl Renderer {
}
}
#[cfg(feature = "pathfinder")]
fn get_vao<'a>(vertex_array_kind: VertexArrayKind,
vaos: &'a RendererVAOs,
gpu_glyph_renderer: &'a GpuGlyphRenderer)
-> &'a VAO {
match vertex_array_kind {
VertexArrayKind::Primitive => &vaos.prim_vao,
VertexArrayKind::Clip => &vaos.clip_vao,
VertexArrayKind::Blur => &vaos.blur_vao,
VertexArrayKind::VectorStencil => &gpu_glyph_renderer.vector_stencil_vao,
VertexArrayKind::VectorCover => &gpu_glyph_renderer.vector_cover_vao,
VertexArrayKind::Border => &vaos.border_vao,
VertexArrayKind::Scale => &vaos.scale_vao,
VertexArrayKind::LineDecoration => &vaos.line_vao,
VertexArrayKind::Gradient => &vaos.gradient_vao,
VertexArrayKind::Resolve => &vaos.resolve_vao,
VertexArrayKind::SvgFilter => &vaos.svg_filter_vao,
}
}
#[cfg(not(feature = "pathfinder"))]
fn get_vao<'a>(vertex_array_kind: VertexArrayKind,
vaos: &'a RendererVAOs,
_: &'a GpuGlyphRenderer)
vaos: &'a RendererVAOs)
-> &'a VAO {
match vertex_array_kind {
VertexArrayKind::Primitive => &vaos.prim_vao,

Просмотреть файл

@ -20,7 +20,6 @@ use crate::capture::CaptureConfig;
use crate::device::TextureFilter;
use euclid::{point2, size2};
use crate::glyph_cache::GlyphCache;
#[cfg(not(feature = "pathfinder"))]
use crate::glyph_cache::GlyphCacheEntry;
use crate::glyph_rasterizer::{BaseFontInstance, FontInstance, GlyphFormat, GlyphKey, GlyphRasterizer};
use crate::gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle};
@ -1429,57 +1428,6 @@ impl ResourceCache {
self.texture_cache.pending_updates()
}
#[cfg(feature = "pathfinder")]
pub fn fetch_glyphs<F>(
&self,
mut font: FontInstance,
glyph_keys: &[GlyphKey],
fetch_buffer: &mut Vec<GlyphFetchResult>,
gpu_cache: &mut GpuCache,
mut f: F,
) where
F: FnMut(TextureSource, GlyphFormat, &[GlyphFetchResult]),
{
debug_assert_eq!(self.state, State::QueryResources);
self.glyph_rasterizer.prepare_font(&mut font);
let mut current_texture_id = TextureSource::Invalid;
let mut current_glyph_format = GlyphFormat::Subpixel;
debug_assert!(fetch_buffer.is_empty());
for (loop_index, key) in glyph_keys.iter().enumerate() {
let (cache_item, glyph_format) =
match self.glyph_rasterizer.get_cache_item_for_glyph(key,
&font,
&self.cached_glyphs,
&self.texture_cache,
&self.cached_render_tasks) {
None => continue,
Some(result) => result,
};
if current_texture_id != cache_item.texture_id ||
current_glyph_format != glyph_format {
if !fetch_buffer.is_empty() {
f(current_texture_id, current_glyph_format, fetch_buffer);
fetch_buffer.clear();
}
current_texture_id = cache_item.texture_id;
current_glyph_format = glyph_format;
}
fetch_buffer.push(GlyphFetchResult {
index_in_text_run: loop_index as i32,
uv_rect_address: gpu_cache.get_address(&cache_item.uv_rect_handle),
});
}
if !fetch_buffer.is_empty() {
f(current_texture_id, current_glyph_format, fetch_buffer);
fetch_buffer.clear();
}
}
#[cfg(not(feature = "pathfinder"))]
pub fn fetch_glyphs<F>(
&self,
mut font: FontInstance,

Просмотреть файл

@ -5,29 +5,23 @@
use api::{ColorF, BorderStyle, FilterPrimitive, MixBlendMode, PipelineId, PremultipliedColorF};
use api::{DocumentLayer, FilterData, ImageFormat, LineOrientation};
use api::units::*;
#[cfg(feature = "pathfinder")]
use api::FontRenderMode;
use crate::batch::{AlphaBatchBuilder, AlphaBatchContainer, BatchTextures, ClipBatcher, resolve_image, BatchBuilder};
use crate::clip::ClipStore;
use crate::clip_scroll_tree::{ClipScrollTree, ROOT_SPATIAL_NODE_INDEX};
use crate::debug_render::DebugItem;
use crate::device::{Texture};
#[cfg(feature = "pathfinder")]
use euclid::{TypedPoint2D, TypedVector2D};
use crate::frame_builder::FrameGlobalResources;
use crate::gpu_cache::{GpuCache, GpuCacheAddress};
use crate::gpu_types::{BorderInstance, SvgFilterInstance, BlurDirection, BlurInstance, PrimitiveHeaders, ScalingInstance};
use crate::gpu_types::{TransformData, TransformPalette, ZBufferIdGenerator};
use crate::internal_types::{CacheTextureId, FastHashMap, SavedTargetIndex, TextureSource, Filter};
#[cfg(feature = "pathfinder")]
use pathfinder_partitioner::mesh::Mesh;
use crate::picture::{RecordedDirtyRegion, SurfaceInfo};
use crate::prim_store::gradient::GRADIENT_FP_STOPS;
use crate::prim_store::{PrimitiveStore, DeferredResolve, PrimitiveScratchBuffer, PrimitiveVisibilityMask};
use crate::profiler::FrameProfileCounters;
use crate::render_backend::{DataStores, FrameId};
use crate::render_task::{BlitSource, RenderTaskAddress, RenderTaskId, RenderTaskKind, SvgFilterTask, SvgFilterInfo};
use crate::render_task::{BlurTask, ClearMode, GlyphTask, RenderTaskLocation, RenderTaskGraph, ScalingTask};
use crate::render_task::{BlurTask, ClearMode, RenderTaskLocation, RenderTaskGraph, ScalingTask};
use crate::resource_cache::ResourceCache;
use std::{cmp, usize, f32, i32, mem};
use crate::texture_allocator::{ArrayAllocationTracker, FreeRectSlice};
@ -331,23 +325,6 @@ pub struct GradientJob {
pub start_stop: [f32; 2],
}
#[cfg(feature = "pathfinder")]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct GlyphJob {
pub mesh: Mesh,
pub target_rect: DeviceIntRect,
pub origin: DeviceIntPoint,
pub subpixel_offset: TypedPoint2D<f32, DevicePixel>,
pub render_mode: FontRenderMode,
pub embolden_amount: TypedVector2D<f32, DevicePixel>,
}
#[cfg(not(feature = "pathfinder"))]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct GlyphJob;
/// Contains the work (in the form of instance arrays) needed to fill a color
/// color output surface (RGBA8).
///
@ -553,10 +530,6 @@ impl RenderTarget for ColorRenderTarget {
RenderTaskKind::LineDecoration(..) => {
panic!("Should not be added to color target!");
}
RenderTaskKind::Glyph(..) => {
// FIXME(pcwalton): Support color glyphs.
panic!("Glyphs should not be added to color target!");
}
RenderTaskKind::Readback(device_rect) => {
self.readbacks.push(device_rect);
}
@ -699,7 +672,6 @@ impl RenderTarget for AlphaRenderTarget {
RenderTaskKind::Border(..) |
RenderTaskKind::LineDecoration(..) |
RenderTaskKind::Gradient(..) |
RenderTaskKind::Glyph(..) |
RenderTaskKind::SvgFilter(..) => {
panic!("BUG: should not be added to alpha target!");
}
@ -791,7 +763,6 @@ pub struct TextureCacheRenderTarget {
pub target_kind: RenderTargetKind,
pub horizontal_blurs: Vec<BlurInstance>,
pub blits: Vec<BlitJob>,
pub glyphs: Vec<GlyphJob>,
pub border_segments_complex: Vec<BorderInstance>,
pub border_segments_solid: Vec<BorderInstance>,
pub clears: Vec<DeviceIntRect>,
@ -805,7 +776,6 @@ impl TextureCacheRenderTarget {
target_kind,
horizontal_blurs: vec![],
blits: vec![],
glyphs: vec![],
border_segments_complex: vec![],
border_segments_solid: vec![],
clears: vec![],
@ -880,9 +850,6 @@ impl TextureCacheRenderTarget {
}
}
}
RenderTaskKind::Glyph(ref mut task_info) => {
self.add_glyph_task(task_info, target_rect.0)
}
RenderTaskKind::Gradient(ref task_info) => {
let mut stops = [0.0; 4];
let mut colors = [PremultipliedColorF::BLACK; 4];
@ -918,21 +885,6 @@ impl TextureCacheRenderTarget {
RenderTaskKind::Test(..) => {}
}
}
#[cfg(feature = "pathfinder")]
fn add_glyph_task(&mut self, task_info: &mut GlyphTask, target_rect: DeviceIntRect) {
self.glyphs.push(GlyphJob {
mesh: task_info.mesh.take().unwrap(),
target_rect,
origin: task_info.origin,
subpixel_offset: task_info.subpixel_offset,
render_mode: task_info.render_mode,
embolden_amount: task_info.embolden_amount,
})
}
#[cfg(not(feature = "pathfinder"))]
fn add_glyph_task(&mut self, _: &mut GlyphTask, _: DeviceIntRect) {}
}
/// Contains the set of `RenderTarget`s specific to the kind of pass.

Просмотреть файл

@ -39,7 +39,6 @@ core-foundation = "0.6"
[features]
default = [ "env_logger" ]
headless = [ "osmesa-sys", "osmesa-src" ]
pathfinder = [ "webrender/pathfinder" ]
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.9"

Просмотреть файл

@ -60,4 +60,3 @@ powershell.exe 'iex (Get-Content -Raw ci-scripts\set-screenresolution.ps1); Set-
export CARGOFLAGS='--verbose --frozen'
export FREETYPE_CMAKE_GENERATOR=Ninja
cmd.exe /c 'ci-scripts\windows-tests.cmd'
cmd.exe /c 'ci-scripts\windows-pathfinder.cmd'