Skip to content

Commit 40ae5d3

Browse files
committed
Initial SIMD glyph advance_for_char_range
1 parent 064b72a commit 40ae5d3

File tree

6 files changed

+368
-248
lines changed

6 files changed

+368
-248
lines changed

components/gfx/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ serde_macros = "0.5"
2323
smallvec = "0.1"
2424
string_cache = "0.1"
2525
time = "0.1.12"
26+
simd = "*"
27+
28+
#[dependencies.simd]
29+
#git = "https://github.com/huonw/simd"
2630

2731
[dependencies.plugins]
2832
path = "../plugins"

components/gfx/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![feature(arc_weak)]
66
#![cfg_attr(any(target_os="linux", target_os = "android"), feature(box_raw))]
77
#![feature(box_syntax)]
8+
#![feature(convert)]
89
#![feature(custom_attribute)]
910
#![feature(custom_derive)]
1011
#![feature(hashmap_hasher)]
@@ -40,6 +41,7 @@ extern crate net_traits;
4041
extern crate util;
4142
extern crate msg;
4243
extern crate rand;
44+
extern crate simd;
4345
extern crate smallvec;
4446
extern crate string_cache;
4547
extern crate style;

components/gfx/text/glyph.rs

+67-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
12
/* This Source Code Form is subject to the terms of the Mozilla Public
23
* License, v. 2.0. If a copy of the MPL was not distributed with this
34
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
45

56
use euclid::point::Point2D;
67
use std::cmp::{Ordering, PartialOrd};
78
use std::mem;
9+
use std::ops::{BitAnd, Shr};
810
use std::u16;
911
use std::vec::Vec;
1012
use util::geometry::Au;
1113
use util::range::{self, Range, RangeIndex, EachIndex};
1214
use util::vec::*;
15+
use simd::u32x4;
16+
1317

1418
/// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing glyph data compactly.
1519
///
@@ -511,6 +515,8 @@ pub struct GlyphStore {
511515
/// `entry_buffer` point to locations in this data structure.
512516
detail_store: DetailedGlyphStore,
513517

518+
has_detailed_glyphs: bool,
519+
514520
is_whitespace: bool,
515521
is_rtl: bool,
516522
}
@@ -533,6 +539,7 @@ impl<'a> GlyphStore {
533539
GlyphStore {
534540
entry_buffer: vec![GlyphEntry::initial(); length],
535541
detail_store: DetailedGlyphStore::new(),
542+
has_detailed_glyphs: false,
536543
is_whitespace: is_whitespace,
537544
is_rtl: is_rtl,
538545
}
@@ -571,6 +578,7 @@ impl<'a> GlyphStore {
571578
(false, true) => GlyphEntry::simple(data.id, data.advance),
572579
(false, false) => {
573580
let glyph = &[DetailedGlyph::new(data.id, data.advance, data.offset)];
581+
self.has_detailed_glyphs = true;
574582
self.detail_store.add_detailed_glyphs_for_entry(i, glyph);
575583
GlyphEntry::complex(data.cluster_start, data.ligature_start, 1)
576584
}
@@ -601,7 +609,7 @@ impl<'a> GlyphStore {
601609
data_for_glyphs[i].advance,
602610
data_for_glyphs[i].offset)
603611
}).collect();
604-
612+
self.has_detailed_glyphs = true;
605613
self.detail_store.add_detailed_glyphs_for_entry(i, &glyphs_vec);
606614
GlyphEntry::complex(first_glyph_data.cluster_start,
607615
first_glyph_data.ligature_start,
@@ -643,10 +651,66 @@ impl<'a> GlyphStore {
643651

644652
#[inline]
645653
pub fn advance_for_char_range(&self, rang: &Range<CharIndex>) -> Au {
646-
self.iter_glyphs_for_char_range(rang)
647-
.fold(Au(0), |advance, (_, glyph)| advance + glyph.advance())
654+
//println!("advance_for_char_range - has_detailed_glyphs: {}", self.has_detailed_glyphs);
655+
if !self.has_detailed_glyphs {
656+
self.advance_for_char_range_simple_glyphs(rang)
657+
} else {
658+
self.iter_glyphs_for_char_range(rang)
659+
.fold(Au(0), |advance, (_, glyph)| advance + glyph.advance())
660+
}
648661
}
649662

663+
#[inline]
664+
fn advance_for_char_range_simple_glyphs(&self, rang: &Range<CharIndex>) -> Au {
665+
//println!("advance_for_char_range_simple_glyphs");
666+
let begin = rang.begin().to_usize();
667+
let len = rang.length().to_usize();
668+
let num: usize = len / 4;
669+
let leftover = len - num * 4;
670+
let mut advance: u32x4 = u32x4::splat(0);
671+
let mask = u32x4::splat(GLYPH_ADVANCE_MASK);
672+
673+
let entry_buf_slice: &[GlyphEntry] = self.entry_buffer.as_slice();
674+
let buf: &[u32] = unsafe { mem::transmute(entry_buf_slice) };
675+
//println!("begin, len, num, leftover: ({:?}, {:?}, {:?}, {:?})",
676+
//begin, len, num, leftover);
677+
for i in 0..num {
678+
let mut v = u32x4::load(buf, begin + i * 4);
679+
v = v.bitand(mask);
680+
v = v.shr(GLYPH_ADVANCE_SHIFT);
681+
advance = advance + v;
682+
}
683+
684+
let left = match leftover {
685+
0 => 0,
686+
1 =>
687+
((self.entry_buffer[begin + len - 1].value &
688+
GLYPH_ADVANCE_MASK)) >> GLYPH_ADVANCE_SHIFT,
689+
690+
2 =>
691+
(((self.entry_buffer[begin + len - 1].value &
692+
GLYPH_ADVANCE_MASK)) >> GLYPH_ADVANCE_SHIFT) +
693+
(((self.entry_buffer[begin + len - 2].value &
694+
GLYPH_ADVANCE_MASK)) >> GLYPH_ADVANCE_SHIFT),
695+
696+
3 => (((self.entry_buffer[begin + len - 1].value &
697+
GLYPH_ADVANCE_MASK)) >> GLYPH_ADVANCE_SHIFT) +
698+
(((self.entry_buffer[begin + len - 2].value &
699+
GLYPH_ADVANCE_MASK)) >> GLYPH_ADVANCE_SHIFT) +
700+
(((self.entry_buffer[begin + len - 3].value &
701+
GLYPH_ADVANCE_MASK)) >> GLYPH_ADVANCE_SHIFT),
702+
_ => panic!("Error leftover should never be > 3"),
703+
};
704+
705+
let adv =
706+
advance.extract(0) +
707+
advance.extract(1) +
708+
advance.extract(2) +
709+
advance.extract(3);
710+
711+
Au((adv + left) as i32)
712+
}
713+
650714
// getter methods
651715
pub fn char_is_space(&self, i: CharIndex) -> bool {
652716
assert!(i < self.char_len());

components/script/cors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl CORSRequest {
191191
header_names.push(header.name().to_owned());
192192
}
193193
header_names.sort();
194-
preflight.headers.set(AccessControlRequestHeaders(header_names.into_iter().map(UniCase).collect()));
194+
//preflight.headers.set(AccessControlRequestHeaders(header_names.into_iter().map(UniCase).collect()));
195195

196196
// Step 8 unnecessary, we don't use the request body
197197
// Step 9, 10 unnecessary, we're writing our own fetch code

0 commit comments

Comments
 (0)