aboutsummaryrefslogtreecommitdiffstats
path: root/components/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'components/gfx')
-rw-r--r--components/gfx/Cargo.toml3
-rw-r--r--components/gfx/font.rs4
-rw-r--r--components/gfx/font_cache_thread.rs12
-rw-r--r--components/gfx/font_context.rs7
-rw-r--r--components/gfx/lib.rs7
-rw-r--r--components/gfx/paint_thread.rs779
-rw-r--r--components/gfx/text/text_run.rs2
7 files changed, 14 insertions, 800 deletions
diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml
index 4bd27945b3f..cc008dc6e87 100644
--- a/components/gfx/Cargo.toml
+++ b/components/gfx/Cargo.toml
@@ -22,7 +22,6 @@ harfbuzz-sys = "0.1"
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
ipc-channel = "0.5"
-layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
lazy_static = "0.2"
libc = "0.2"
log = "0.3.5"
@@ -31,8 +30,6 @@ msg = {path = "../msg"}
net_traits = {path = "../net_traits"}
ordered-float = "0.2.2"
plugins = {path = "../plugins"}
-profile_traits = {path = "../profile_traits"}
-rand = "0.3"
range = {path = "../range"}
rustc-serialize = "0.3"
serde = "0.8"
diff --git a/components/gfx/font.rs b/components/gfx/font.rs
index c955c042eff..8a0377cd2b0 100644
--- a/components/gfx/font.rs
+++ b/components/gfx/font.rs
@@ -112,7 +112,7 @@ pub struct Font {
shaper: Option<Shaper>,
shape_cache: RefCell<HashMap<ShapeCacheEntry, Arc<GlyphStore>>>,
glyph_advance_cache: RefCell<HashMap<u32, FractionalPixel>>,
- pub font_key: Option<webrender_traits::FontKey>,
+ pub font_key: webrender_traits::FontKey,
}
impl Font {
@@ -121,7 +121,7 @@ impl Font {
descriptor: FontTemplateDescriptor,
requested_pt_size: Au,
actual_pt_size: Au,
- font_key: Option<webrender_traits::FontKey>) -> Font {
+ font_key: webrender_traits::FontKey) -> Font {
let metrics = handle.metrics();
Font {
handle: handle,
diff --git a/components/gfx/font_cache_thread.rs b/components/gfx/font_cache_thread.rs
index c3fcf7dfc07..e921f41fcf9 100644
--- a/components/gfx/font_cache_thread.rs
+++ b/components/gfx/font_cache_thread.rs
@@ -349,16 +349,18 @@ impl FontCache {
}
fn get_font_template_info(&mut self, template: Arc<FontTemplateData>) -> FontTemplateInfo {
- let webrender_fonts = &mut self.webrender_fonts;
- let font_key = self.webrender_api.as_ref().map(|webrender_api| {
- *webrender_fonts.entry(template.identifier.clone()).or_insert_with(|| {
+ let mut font_key = None;
+
+ if let Some(ref webrender_api) = self.webrender_api {
+ let webrender_fonts = &mut self.webrender_fonts;
+ font_key = Some(*webrender_fonts.entry(template.identifier.clone()).or_insert_with(|| {
match (template.bytes_if_in_memory(), template.native_font()) {
(Some(bytes), _) => webrender_api.add_raw_font(bytes),
(None, Some(native_font)) => webrender_api.add_native_font(native_font),
(None, None) => webrender_api.add_raw_font(template.bytes().clone()),
}
- })
- });
+ }));
+ }
FontTemplateInfo {
font_template: template,
diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs
index d89962b869a..1ffa1b32c21 100644
--- a/components/gfx/font_context.rs
+++ b/components/gfx/font_context.rs
@@ -109,7 +109,7 @@ impl FontContext {
descriptor: FontTemplateDescriptor,
pt_size: Au,
variant: font_variant::T,
- font_key: Option<webrender_traits::FontKey>) -> Result<Font, ()> {
+ font_key: webrender_traits::FontKey) -> Result<Font, ()> {
// TODO: (Bug #3463): Currently we only support fake small-caps
// painting. We should also support true small-caps (where the
// font supports it) in the future.
@@ -197,7 +197,8 @@ impl FontContext {
desc.clone(),
style.font_size,
style.font_variant,
- template_info.font_key);
+ template_info.font_key
+ .expect("No font key present!"));
let font = match layout_font {
Ok(layout_font) => {
let layout_font = Rc::new(RefCell::new(layout_font));
@@ -242,7 +243,7 @@ impl FontContext {
desc.clone(),
style.font_size,
style.font_variant,
- template_info.font_key);
+ template_info.font_key.expect("No font key present!"));
match layout_font {
Ok(layout_font) => {
let layout_font = Rc::new(RefCell::new(layout_font));
diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs
index 59045550660..763f55096c6 100644
--- a/components/gfx/lib.rs
+++ b/components/gfx/lib.rs
@@ -9,7 +9,6 @@
#![feature(box_syntax)]
#![feature(custom_attribute)]
#![feature(custom_derive)]
-#![feature(mpsc_select)]
#![feature(plugin)]
#![feature(proc_macro)]
#![feature(range_contains)]
@@ -57,7 +56,6 @@ extern crate harfbuzz_sys as harfbuzz;
extern crate heapsize;
extern crate ipc_channel;
-extern crate layers;
#[allow(unused_extern_crates)]
#[macro_use]
extern crate lazy_static;
@@ -69,9 +67,6 @@ extern crate msg;
extern crate net_traits;
extern crate ordered_float;
#[macro_use]
-extern crate profile_traits;
-extern crate rand;
-#[macro_use]
extern crate range;
extern crate rustc_serialize;
extern crate serde;
@@ -110,8 +105,6 @@ pub mod font_cache_thread;
pub mod font_context;
pub mod font_template;
-pub mod paint_thread;
-
// Platform-specific implementations.
#[allow(unsafe_code)]
mod platform;
diff --git a/components/gfx/paint_thread.rs b/components/gfx/paint_thread.rs
deleted file mode 100644
index a17a0ee2bb7..00000000000
--- a/components/gfx/paint_thread.rs
+++ /dev/null
@@ -1,779 +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/. */
-
-//! The thread that handles all painting.
-
-use app_units::Au;
-use azure::AzFloat;
-use azure::azure_hl::{BackendType, Color, DrawTarget, SurfaceFormat};
-use display_list::{DisplayItem, DisplayList, DisplayListTraversal};
-use display_list::{LayerInfo, StackingContext, StackingContextType};
-use euclid::Matrix4D;
-use euclid::point::Point2D;
-use euclid::rect::{Rect, TypedRect};
-use euclid::size::Size2D;
-use font_cache_thread::FontCacheThread;
-use font_context::FontContext;
-use gfx_traits::{ChromeToPaintMsg, Epoch, LayerId, LayerKind, LayerProperties};
-use gfx_traits::{PaintListener, PaintRequest, StackingContextId};
-use layers::layers::{BufferRequest, LayerBuffer, LayerBufferSet};
-use layers::platform::surface::{NativeDisplay, NativeSurface};
-use msg::constellation_msg::PipelineId;
-use paint_context::PaintContext;
-use profile_traits::mem;
-use profile_traits::time;
-use rand::{self, Rng};
-use std::borrow::ToOwned;
-use std::collections::HashMap;
-use std::mem as std_mem;
-use std::sync::Arc;
-use std::sync::mpsc::{Receiver, Sender, channel};
-use style::thread_state;
-use url::Url;
-use util::geometry::ExpandToPixelBoundaries;
-use util::opts;
-use util::thread;
-
-#[derive(Clone, HeapSizeOf)]
-struct PaintLayer {
- /// The LayerProperties, which describe the layer in a way that the Compositor
- /// can consume.
- pub layer_properties: LayerProperties,
-
- /// The StackingContextId of the StackingContext that is the immediate
- /// parent of this layer. This is used to ensure applying the proper transform
- /// when painting.
- pub starting_stacking_context_id: StackingContextId,
-
- /// The indices (in the DisplayList) to the first and last display item
- /// that are the contents of this layer.
- pub display_list_indices: Option<(usize, usize)>,
-
- /// When painting, whether to draw the start by entering the surrounding StackingContext
- /// or simply to draw the single item this PaintLayer contains.
- pub single_item: bool,
-
- /// The layer's bounds start at the overflow origin, but display items are
- /// positioned relative to the stacking context bounds, so we need to
- /// offset by the overflow rect (which will be in the coordinate system of
- /// the stacking context bounds).
- pub display_list_origin: Point2D<f32>
-}
-
-impl PaintLayer {
- fn new_from_stacking_context(layer_info: &LayerInfo,
- stacking_context: &StackingContext,
- parent_origin: &Point2D<Au>,
- transform: &Matrix4D<f32>,
- perspective: &Matrix4D<f32>,
- parent_id: Option<LayerId>)
- -> PaintLayer {
- let bounds = Rect::new(stacking_context.bounds.origin + stacking_context.overflow.origin,
- stacking_context.overflow.size);
- let layer_boundaries = Rect::new(
- Point2D::new((parent_origin.x + bounds.min_x()).to_nearest_px() as f32,
- (parent_origin.y + bounds.min_y()).to_nearest_px() as f32),
- Size2D::new(bounds.size.width.to_nearest_px() as f32,
- bounds.size.height.to_nearest_px() as f32));
-
- let transform = transform.pre_mul(&stacking_context.transform);
- let perspective = perspective.pre_mul(&stacking_context.perspective);
- let establishes_3d_context = stacking_context.establishes_3d_context;
- let scrolls_overflow_area = stacking_context.scrolls_overflow_area;
-
- PaintLayer {
- layer_properties: LayerProperties {
- id: layer_info.layer_id,
- parent_id: parent_id,
- rect: layer_boundaries,
- background_color: layer_info.background_color,
- scroll_policy: layer_info.scroll_policy,
- transform: transform,
- perspective: perspective,
- establishes_3d_context: establishes_3d_context,
- scrolls_overflow_area: scrolls_overflow_area,
- subpage_pipeline_id: layer_info.subpage_pipeline_id,
- },
- starting_stacking_context_id: stacking_context.id,
- display_list_indices: None,
- single_item: false,
- display_list_origin: Point2D::new(stacking_context.overflow.origin.x.to_f32_px(),
- stacking_context.overflow.origin.y.to_f32_px()),
- }
- }
-
- fn new_for_display_item(layer_info: &LayerInfo,
- item_bounds: &Rect<Au>,
- parent_origin: &Point2D<Au>,
- transform: &Matrix4D<f32>,
- perspective: &Matrix4D<f32>,
- parent_id: Option<LayerId>,
- stacking_context_id: StackingContextId,
- item_index: usize)
- -> PaintLayer {
- let bounds = item_bounds.expand_to_px_boundaries();
- let layer_boundaries = Rect::new(
- Point2D::new((parent_origin.x + bounds.min_x()).to_nearest_px() as f32,
- (parent_origin.y + bounds.min_y()).to_nearest_px() as f32),
- Size2D::new(bounds.size.width.to_nearest_px() as f32,
- bounds.size.height.to_nearest_px() as f32));
-
- PaintLayer {
- layer_properties: LayerProperties {
- id: layer_info.layer_id,
- parent_id: parent_id,
- rect: layer_boundaries,
- background_color: layer_info.background_color,
- scroll_policy: layer_info.scroll_policy,
- transform: *transform,
- perspective: *perspective,
- establishes_3d_context: false,
- scrolls_overflow_area: false,
- subpage_pipeline_id: layer_info.subpage_pipeline_id,
- },
- starting_stacking_context_id: stacking_context_id,
- display_list_indices: Some((item_index, item_index)),
- single_item: true,
- display_list_origin: Point2D::new(bounds.origin.x.to_f32_px(),
- bounds.origin.y.to_f32_px()),
- }
- }
-
- fn add_item(&mut self, index: usize) {
- let indices = match self.display_list_indices {
- Some((first, _)) => (first, index),
- None => (index, index),
- };
- self.display_list_indices = Some(indices);
- }
-
- fn make_companion_layer(&mut self) {
- self.layer_properties.id = self.layer_properties.id.companion_layer_id();
- self.display_list_indices = None;
- }
-}
-
-struct LayerCreator {
- layers: Vec<PaintLayer>,
- layer_details_stack: Vec<PaintLayer>,
- current_layer: Option<PaintLayer>,
-}
-
-impl LayerCreator {
- fn create_layers_with_display_list<'a>(display_list: &'a DisplayList) -> Vec<PaintLayer> {
- let mut layer_creator = LayerCreator {
- layers: Vec::new(),
- layer_details_stack: Vec::new(),
- current_layer: None,
- };
- let mut traversal = DisplayListTraversal::new(display_list);
- layer_creator.process_stacking_context_items(&mut traversal,
- &Point2D::zero(),
- &Matrix4D::identity(),
- &Matrix4D::identity());
- layer_creator.layers
- }
-
- fn finalize_current_layer(&mut self) {
- if let Some(current_layer) = self.current_layer.take() {
- self.layers.push(current_layer);
- }
- }
-
- fn current_parent_layer_id(&self) -> Option<LayerId> {
- self.layer_details_stack.last().as_ref().map(|layer|
- layer.layer_properties.id
- )
- }
-
- fn current_parent_stacking_context_id(&self) -> StackingContextId {
- self.layer_details_stack.last().unwrap().starting_stacking_context_id
- }
-
- fn create_layers_for_stacking_context<'a>(&mut self,
- stacking_context: &StackingContext,
- traversal: &mut DisplayListTraversal<'a>,
- parent_origin: &Point2D<Au>,
- transform: &Matrix4D<f32>,
- perspective: &Matrix4D<f32>) {
- if let Some(ref layer_info) = stacking_context.layer_info {
- self.finalize_current_layer();
- let new_layer = PaintLayer::new_from_stacking_context(
- layer_info,
- stacking_context,
- parent_origin,
- transform,
- perspective,
- self.current_parent_layer_id());
- self.layer_details_stack.push(new_layer.clone());
- self.current_layer = Some(new_layer);
-
- // When there is a new layer, the transforms and origin are handled by
- // the compositor, so the new transform and perspective matrices are
- // just the identity.
- //
- // The origin for child layers which might be somewhere other than the
- // layer origin, since layer boundaries are expanded to include overflow.
- self.process_stacking_context_items(traversal,
- &-stacking_context.overflow.origin,
- &Matrix4D::identity(),
- &Matrix4D::identity());
- self.finalize_current_layer();
- self.layer_details_stack.pop();
- return;
- }
-
- debug_assert!(stacking_context.context_type == StackingContextType::Real);
- self.process_stacking_context_items(traversal,
- &(stacking_context.bounds.origin + *parent_origin),
- &transform.pre_mul(&stacking_context.transform),
- &perspective.pre_mul(&stacking_context.perspective));
- }
-
- fn process_stacking_context_items<'a>(&mut self,
- traversal: &mut DisplayListTraversal<'a>,
- parent_origin: &Point2D<Au>,
- transform: &Matrix4D<f32>,
- perspective: &Matrix4D<f32>) {
- while let Some(item) = traversal.next() {
- match item {
- &DisplayItem::PushStackingContextClass(ref stacking_context_item) => {
- self.create_layers_for_stacking_context(&stacking_context_item.stacking_context,
- traversal,
- parent_origin,
- transform,
- perspective);
- }
- &DisplayItem::PopStackingContextClass(_) => return,
- _ => {
- self.create_layers_for_item(traversal.previous_item_id(),
- item,
- parent_origin,
- transform,
- perspective);
- }
- }
- }
- }
-
-
- fn create_layers_for_item<'a>(&mut self,
- current_item_index: usize,
- item: &DisplayItem,
- parent_origin: &Point2D<Au>,
- transform: &Matrix4D<f32>,
- perspective: &Matrix4D<f32>) {
- if let &DisplayItem::LayeredItemClass(ref layered_item) = item {
- // We need to finalize the last layer here before incrementing the item
- // index, otherwise this item will be placed into the parent layer.
- self.finalize_current_layer();
- let layer = PaintLayer::new_for_display_item(
- &layered_item.layer_info,
- &layered_item.item.bounds(),
- parent_origin,
- transform,
- perspective,
- self.current_parent_layer_id(),
- self.current_parent_stacking_context_id(),
- current_item_index);
- self.layers.push(layer);
- return;
- }
-
- // If we don't have a current layer, we are an item that belonged to a
- // previous layer that was finalized by a child layer. We need to
- // resurrect a copy of the original ancestor layer to ensure that this
- // item is ordered on top of the child layers when painted.
- if self.current_layer.is_none() {
- let mut new_layer = self.layer_details_stack.pop().unwrap();
- new_layer.make_companion_layer();
-
- if new_layer.layer_properties.parent_id == None {
- new_layer.layer_properties.parent_id =
- Some(new_layer.layer_properties.id.original());
- }
-
- self.layer_details_stack.push(new_layer.clone());
- self.current_layer = Some(new_layer);
- }
-
- if let Some(ref mut current_layer) = self.current_layer {
- current_layer.add_item(current_item_index);
- }
- }
-}
-
-pub enum Msg {
- FromLayout(LayoutToPaintMsg),
- FromChrome(ChromeToPaintMsg),
-}
-
-#[derive(Deserialize, Serialize)]
-pub enum LayoutToPaintMsg {
- PaintInit(Epoch, Arc<DisplayList>),
- Exit,
-}
-
-pub struct PaintThread<C> {
- id: PipelineId,
- _url: Url,
- layout_to_paint_port: Receiver<LayoutToPaintMsg>,
- chrome_to_paint_port: Receiver<ChromeToPaintMsg>,
- compositor: C,
-
- /// A channel to the time profiler.
- time_profiler_chan: time::ProfilerChan,
-
- /// The root paint layer sent to us by the layout thread.
- root_display_list: Option<Arc<DisplayList>>,
-
- /// A map that associates LayerIds with their corresponding layers.
- layer_map: HashMap<LayerId, Arc<PaintLayer>>,
-
- /// Permission to send paint messages to the compositor
- paint_permission: bool,
-
- /// The current epoch counter is passed by the layout thread
- current_epoch: Option<Epoch>,
-
- /// Communication handles to each of the worker threads.
- worker_threads: Vec<WorkerThreadProxy>,
-}
-
-// If we implement this as a function, we get borrowck errors from borrowing
-// the whole PaintThread struct.
-macro_rules! native_display(
- ($thread:expr) => (
- $thread.native_display.as_ref().expect("Need a graphics context to do painting")
- )
-);
-
-impl<C> PaintThread<C> where C: PaintListener + Send + 'static {
- pub fn create(id: PipelineId,
- url: Url,
- chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
- layout_to_paint_port: Receiver<LayoutToPaintMsg>,
- chrome_to_paint_port: Receiver<ChromeToPaintMsg>,
- mut compositor: C,
- font_cache_thread: FontCacheThread,
- time_profiler_chan: time::ProfilerChan,
- mem_profiler_chan: mem::ProfilerChan) {
- thread::spawn_named(format!("PaintThread {:?}", id), move || {
- thread_state::initialize(thread_state::PAINT);
- PipelineId::install(id);
-
- let native_display = compositor.native_display();
- let worker_threads = WorkerThreadProxy::spawn(native_display,
- font_cache_thread,
- time_profiler_chan.clone());
-
- let mut paint_thread = PaintThread {
- id: id,
- _url: url,
- layout_to_paint_port: layout_to_paint_port,
- chrome_to_paint_port: chrome_to_paint_port,
- compositor: compositor,
- time_profiler_chan: time_profiler_chan,
- root_display_list: None,
- layer_map: HashMap::new(),
- paint_permission: false,
- current_epoch: None,
- worker_threads: worker_threads,
- };
-
- let reporter_name = format!("paint-reporter-{}", id);
- mem_profiler_chan.run_with_memory_reporting(|| {
- paint_thread.start();
- }, reporter_name, chrome_to_paint_chan, ChromeToPaintMsg::CollectReports);
-
- // Tell all the worker threads to shut down.
- for worker_thread in &mut paint_thread.worker_threads {
- worker_thread.exit()
- }
- });
- }
-
- #[allow(unsafe_code)]
- fn start(&mut self) {
- debug!("PaintThread: beginning painting loop");
-
- loop {
- let message = {
- let layout_to_paint = &self.layout_to_paint_port;
- let chrome_to_paint = &self.chrome_to_paint_port;
- select! {
- msg = layout_to_paint.recv() =>
- Msg::FromLayout(msg.expect("expected message from layout")),
- msg = chrome_to_paint.recv() =>
- Msg::FromChrome(msg.expect("expected message from chrome"))
- }
- };
-
- match message {
- Msg::FromLayout(LayoutToPaintMsg::PaintInit(epoch, display_list)) => {
- self.current_epoch = Some(epoch);
- self.root_display_list = Some(display_list);
-
- if self.paint_permission {
- self.initialize_layers();
- }
- }
- Msg::FromChrome(ChromeToPaintMsg::Paint(requests, frame_tree_id)) => {
- if self.paint_permission && self.root_display_list.is_some() {
- let mut replies = Vec::new();
- for PaintRequest { buffer_requests, scale, layer_id, epoch, layer_kind }
- in requests {
- if self.current_epoch == Some(epoch) {
- self.paint(&mut replies, buffer_requests, scale, layer_id, layer_kind);
- } else {
- debug!("PaintThread: Ignoring requests with epoch mismatch: {:?} != {:?}",
- self.current_epoch,
- epoch);
- self.compositor.ignore_buffer_requests(buffer_requests);
- }
- }
-
- debug!("PaintThread: returning surfaces");
- self.compositor.assign_painted_buffers(self.id,
- self.current_epoch.unwrap(),
- replies,
- frame_tree_id);
- }
- }
- Msg::FromChrome(ChromeToPaintMsg::PaintPermissionGranted) => {
- self.paint_permission = true;
-
- if self.root_display_list.is_some() {
- self.initialize_layers();
- }
- }
- Msg::FromChrome(ChromeToPaintMsg::PaintPermissionRevoked) => {
- self.paint_permission = false;
- }
- Msg::FromChrome(ChromeToPaintMsg::CollectReports(ref channel)) => {
- // FIXME(njn): should eventually measure the paint thread.
- channel.send(Vec::new())
- }
- Msg::FromLayout(LayoutToPaintMsg::Exit) => {
- // Ask the compositor to remove any layers it is holding for this paint thread.
- // FIXME(mrobinson): This can probably move back to the constellation now.
- debug!("PaintThread: Exiting.");
- self.compositor.notify_paint_thread_exiting(self.id);
-
- break;
- }
- Msg::FromChrome(ChromeToPaintMsg::Exit) => {
- // Ask the compositor to remove any layers it is holding for this paint thread.
- // FIXME(mrobinson): This can probably move back to the constellation now.
- debug!("PaintThread: Exiting.");
- self.compositor.notify_paint_thread_exiting(self.id);
-
- break;
- }
- }
- }
- }
-
- /// Paints one layer and places the painted tiles in `replies`.
- fn paint(&mut self,
- replies: &mut Vec<(LayerId, Box<LayerBufferSet>)>,
- mut tiles: Vec<BufferRequest>,
- scale: f32,
- layer_id: LayerId,
- layer_kind: LayerKind) {
- time::profile(time::ProfilerCategory::Painting, None, self.time_profiler_chan.clone(), || {
- let display_list = match self.root_display_list {
- Some(ref display_list) => display_list.clone(),
- None => return,
- };
-
- // Bail out if there is no appropriate layer.
- let layer = match self.layer_map.get(&layer_id) {
- Some(layer) => layer.clone(),
- None => return,
- };
-
- // Divide up the layer into tiles and distribute them to workers via a simple round-
- // robin strategy.
- let tiles = std_mem::replace(&mut tiles, Vec::new());
- let tile_count = tiles.len();
- for (i, tile) in tiles.into_iter().enumerate() {
- let thread_id = i % self.worker_threads.len();
- self.worker_threads[thread_id].paint_tile(thread_id,
- tile,
- display_list.clone(),
- layer.clone(),
- scale,
- layer_kind);
- }
- let new_buffers = (0..tile_count).map(|i| {
- let thread_id = i % self.worker_threads.len();
- self.worker_threads[thread_id].painted_tile_buffer()
- }).collect();
-
- let layer_buffer_set = box LayerBufferSet {
- buffers: new_buffers,
- };
- replies.push((layer_id, layer_buffer_set));
- })
- }
-
- fn initialize_layers(&mut self) {
- let root_display_list = match self.root_display_list {
- None => return,
- Some(ref root_display_list) => root_display_list,
- };
- let layers = LayerCreator::create_layers_with_display_list(&root_display_list);
- let properties = layers.iter().map(|layer| layer.layer_properties.clone()).collect();
- self.compositor.initialize_layers_for_pipeline(self.id,
- properties,
- self.current_epoch.unwrap());
- self.layer_map.clear();
- for layer in layers.into_iter() {
- self.layer_map.insert(layer.layer_properties.id, Arc::new(layer));
- }
- }
-}
-
-struct WorkerThreadProxy {
- sender: Sender<MsgToWorkerThread>,
- receiver: Receiver<MsgFromWorkerThread>,
-}
-
-impl WorkerThreadProxy {
- fn spawn(native_display: Option<NativeDisplay>,
- font_cache_thread: FontCacheThread,
- time_profiler_chan: time::ProfilerChan)
- -> Vec<WorkerThreadProxy> {
- // Don't make any paint threads if we're using WebRender. They're just a waste of
- // resources.
- if opts::get().use_webrender {
- return vec![]
- }
-
- let thread_count = opts::get().paint_threads;
- (0..thread_count).map(|_| {
- let (from_worker_sender, from_worker_receiver) = channel();
- let (to_worker_sender, to_worker_receiver) = channel();
- let font_cache_thread = font_cache_thread.clone();
- let time_profiler_chan = time_profiler_chan.clone();
- thread::spawn_named("PaintWorker".to_owned(), move || {
- let mut worker_thread = WorkerThread::new(from_worker_sender,
- to_worker_receiver,
- native_display,
- font_cache_thread,
- time_profiler_chan);
- worker_thread.main();
- });
- WorkerThreadProxy {
- receiver: from_worker_receiver,
- sender: to_worker_sender,
- }
- }).collect()
- }
-
- fn paint_tile(&mut self,
- thread_id: usize,
- tile: BufferRequest,
- display_list: Arc<DisplayList>,
- paint_layer: Arc<PaintLayer>,
- scale: f32,
- layer_kind: LayerKind) {
- let msg = MsgToWorkerThread::PaintTile(thread_id,
- tile,
- display_list,
- paint_layer,
- scale,
- layer_kind);
- self.sender.send(msg).unwrap()
- }
-
- fn painted_tile_buffer(&mut self) -> Box<LayerBuffer> {
- match self.receiver.recv().unwrap() {
- MsgFromWorkerThread::PaintedTile(layer_buffer) => layer_buffer,
- }
- }
-
- fn exit(&mut self) {
- self.sender.send(MsgToWorkerThread::Exit).unwrap()
- }
-}
-
-struct WorkerThread {
- sender: Sender<MsgFromWorkerThread>,
- receiver: Receiver<MsgToWorkerThread>,
- native_display: Option<NativeDisplay>,
- font_context: Box<FontContext>,
- time_profiler_sender: time::ProfilerChan,
-}
-
-impl WorkerThread {
- fn new(sender: Sender<MsgFromWorkerThread>,
- receiver: Receiver<MsgToWorkerThread>,
- native_display: Option<NativeDisplay>,
- font_cache_thread: FontCacheThread,
- time_profiler_sender: time::ProfilerChan)
- -> WorkerThread {
- WorkerThread {
- sender: sender,
- receiver: receiver,
- native_display: native_display,
- font_context: box FontContext::new(font_cache_thread.clone()),
- time_profiler_sender: time_profiler_sender,
- }
- }
-
- fn main(&mut self) {
- loop {
- match self.receiver.recv().unwrap() {
- MsgToWorkerThread::Exit => break,
- MsgToWorkerThread::PaintTile(thread_id,
- tile,
- display_list,
- paint_layer,
- scale,
- layer_kind) => {
- let buffer = self.optimize_and_paint_tile(thread_id,
- tile,
- display_list,
- paint_layer,
- scale,
- layer_kind);
- self.sender.send(MsgFromWorkerThread::PaintedTile(buffer)).unwrap()
- }
- }
- }
- }
-
- fn optimize_and_paint_tile(&mut self,
- thread_id: usize,
- mut tile: BufferRequest,
- display_list: Arc<DisplayList>,
- paint_layer: Arc<PaintLayer>,
- scale: f32,
- layer_kind: LayerKind)
- -> Box<LayerBuffer> {
- let size = Size2D::new(tile.screen_rect.size.width as i32,
- tile.screen_rect.size.height as i32);
- let mut buffer = self.create_layer_buffer(&mut tile, scale);
- let draw_target = DrawTarget::new(BackendType::Skia, size, SurfaceFormat::B8G8R8A8);
-
- {
- // Build the paint context.
- let mut paint_context = PaintContext {
- draw_target: draw_target.clone(),
- font_context: &mut self.font_context,
- page_rect: TypedRect::from_untyped(&tile.page_rect.translate(&paint_layer.display_list_origin)),
- screen_rect: TypedRect::from_untyped(&tile.screen_rect),
- clip_rect: None,
- transient_clip: None,
- layer_kind: layer_kind,
- subpixel_offset: Point2D::zero(),
- };
-
- // Apply the translation to paint the tile we want.
- let matrix = Matrix4D::identity();
- let matrix = matrix.pre_scaled(scale as AzFloat, scale as AzFloat, 1.0);
- let tile_bounds = tile.page_rect.translate(&paint_layer.display_list_origin);
- let matrix = matrix.pre_translated(-tile_bounds.origin.x as AzFloat,
- -tile_bounds.origin.y as AzFloat,
- 0.0);
-
- // Clear the buffer.
- paint_context.clear();
-
- // Draw the display list.
- time::profile(time::ProfilerCategory::PaintingPerTile,
- None,
- self.time_profiler_sender.clone(), || {
- if let Some((start, end)) = paint_layer.display_list_indices {
- if paint_layer.single_item {
- display_list.draw_item_at_index_into_context(
- &mut paint_context, &matrix, start);
- } else {
- display_list.draw_into_context(
- &mut paint_context,
- &matrix,
- paint_layer.starting_stacking_context_id,
- start,
- end);
- }
- }
- paint_context.draw_target.flush();
- });
-
- if opts::get().show_debug_parallel_paint {
- // Overlay a transparent solid color to identify the thread that
- // painted this tile.
- let color = THREAD_TINT_COLORS[thread_id % THREAD_TINT_COLORS.len()];
- paint_context.draw_solid_color(&Rect::new(Point2D::new(Au(0), Au(0)),
- Size2D::new(Au::from_px(size.width),
- Au::from_px(size.height))),
- color);
- }
- if opts::get().paint_flashing {
- // Overlay a random transparent color.
- let color = *rand::thread_rng().choose(&THREAD_TINT_COLORS[..]).unwrap();
- paint_context.draw_solid_color(&Rect::new(Point2D::new(Au(0), Au(0)),
- Size2D::new(Au::from_px(size.width),
- Au::from_px(size.height))),
- color);
- }
- }
-
- // Extract the texture from the draw target and place it into its slot in the buffer.
- // Upload it first.
- draw_target.snapshot().get_data_surface().with_data(|data| {
- buffer.native_surface.upload(native_display!(self), data);
- debug!("painting worker thread uploading to native surface {}",
- buffer.native_surface.get_id());
- });
-
- draw_target.finish();
- buffer
- }
-
- fn create_layer_buffer(&mut self,
- tile: &mut BufferRequest,
- scale: f32)
- -> Box<LayerBuffer> {
- // Create an empty native surface. We mark it as not leaking
- // in case it dies in transit to the compositor thread.
- let width = tile.screen_rect.size.width;
- let height = tile.screen_rect.size.height;
- let mut native_surface = tile.native_surface.take().unwrap_or_else(|| {
- NativeSurface::new(native_display!(self), Size2D::new(width as i32, height as i32))
- });
- native_surface.mark_wont_leak();
-
- box LayerBuffer {
- native_surface: native_surface,
- rect: tile.page_rect,
- screen_pos: tile.screen_rect,
- resolution: scale,
- painted_with_cpu: true,
- content_age: tile.content_age,
- }
- }
-}
-
-enum MsgToWorkerThread {
- Exit,
- PaintTile(usize, BufferRequest, Arc<DisplayList>, Arc<PaintLayer>, f32, LayerKind),
-}
-
-enum MsgFromWorkerThread {
- PaintedTile(Box<LayerBuffer>),
-}
-
-pub static THREAD_TINT_COLORS: [Color; 8] = [
- Color { r: 6.0 / 255.0, g: 153.0 / 255.0, b: 198.0 / 255.0, a: 0.7 },
- Color { r: 255.0 / 255.0, g: 212.0 / 255.0, b: 83.0 / 255.0, a: 0.7 },
- Color { r: 116.0 / 255.0, g: 29.0 / 255.0, b: 109.0 / 255.0, a: 0.7 },
- Color { r: 204.0 / 255.0, g: 158.0 / 255.0, b: 199.0 / 255.0, a: 0.7 },
- Color { r: 242.0 / 255.0, g: 46.0 / 255.0, b: 121.0 / 255.0, a: 0.7 },
- Color { r: 116.0 / 255.0, g: 203.0 / 255.0, b: 196.0 / 255.0, a: 0.7 },
- Color { r: 255.0 / 255.0, g: 249.0 / 255.0, b: 201.0 / 255.0, a: 0.7 },
- Color { r: 137.0 / 255.0, g: 196.0 / 255.0, b: 78.0 / 255.0, a: 0.7 },
-];
diff --git a/components/gfx/text/text_run.rs b/components/gfx/text/text_run.rs
index 7ab8f4a870f..db65dc49142 100644
--- a/components/gfx/text/text_run.rs
+++ b/components/gfx/text/text_run.rs
@@ -29,7 +29,7 @@ pub struct TextRun {
pub font_template: Arc<FontTemplateData>,
pub actual_pt_size: Au,
pub font_metrics: FontMetrics,
- pub font_key: Option<webrender_traits::FontKey>,
+ pub font_key: webrender_traits::FontKey,
/// The glyph runs that make up this text run.
pub glyphs: Arc<Vec<GlyphRun>>,
pub bidi_level: u8,