Auto merge of #13711 - glennw:remove-old-renderer, r=larsbergstrom

Remove old rendering backend.

This removes paint threads, rust-layers dependency, and changes
optional webrender types to be required.

The use_webrender option has been removed, however I've left
the "-w" command line option in place for now so that wpt
runner can continue to pass that. Once it's removed from there
we can also remove the -w option.

Once this stage is complete, it should be fine to change the
display list building code to generate webrender display
lists directly and avoid the conversion step.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13711)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-10-17 19:22:20 -05:00 committed by GitHub
commit f96718d03d
55 changed files with 422 additions and 3611 deletions

View file

@ -58,8 +58,8 @@ pub struct CanvasPaintThread<'a> {
path_builder: PathBuilder, path_builder: PathBuilder,
state: CanvasPaintState<'a>, state: CanvasPaintState<'a>,
saved_states: Vec<CanvasPaintState<'a>>, saved_states: Vec<CanvasPaintState<'a>>,
webrender_api: Option<webrender_traits::RenderApi>, webrender_api: webrender_traits::RenderApi,
webrender_image_key: Option<webrender_traits::ImageKey>, webrender_image_key: webrender_traits::ImageKey,
} }
#[derive(Clone)] #[derive(Clone)]
@ -100,12 +100,12 @@ impl<'a> CanvasPaintState<'a> {
impl<'a> CanvasPaintThread<'a> { impl<'a> CanvasPaintThread<'a> {
fn new(size: Size2D<i32>, fn new(size: Size2D<i32>,
webrender_api_sender: Option<webrender_traits::RenderApiSender>, webrender_api_sender: webrender_traits::RenderApiSender,
antialias: bool) -> CanvasPaintThread<'a> { antialias: bool) -> CanvasPaintThread<'a> {
let draw_target = CanvasPaintThread::create(size); let draw_target = CanvasPaintThread::create(size);
let path_builder = draw_target.create_path_builder(); let path_builder = draw_target.create_path_builder();
let webrender_api = webrender_api_sender.map(|wr| wr.create_api()); let webrender_api = webrender_api_sender.create_api();
let webrender_image_key = webrender_api.as_ref().map(|wr| wr.alloc_image()); let webrender_image_key = webrender_api.alloc_image();
CanvasPaintThread { CanvasPaintThread {
drawtarget: draw_target, drawtarget: draw_target,
path_builder: path_builder, path_builder: path_builder,
@ -119,7 +119,7 @@ impl<'a> CanvasPaintThread<'a> {
/// Creates a new `CanvasPaintThread` and returns an `IpcSender` to /// Creates a new `CanvasPaintThread` and returns an `IpcSender` to
/// communicate with it. /// communicate with it.
pub fn start(size: Size2D<i32>, pub fn start(size: Size2D<i32>,
webrender_api_sender: Option<webrender_traits::RenderApiSender>, webrender_api_sender: webrender_traits::RenderApiSender,
antialias: bool) antialias: bool)
-> IpcSender<CanvasMsg> { -> IpcSender<CanvasMsg> {
let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap(); let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap();
@ -542,14 +542,12 @@ impl<'a> CanvasPaintThread<'a> {
fn send_data(&mut self, chan: IpcSender<CanvasData>) { fn send_data(&mut self, chan: IpcSender<CanvasData>) {
self.drawtarget.snapshot().get_data_surface().with_data(|element| { self.drawtarget.snapshot().get_data_surface().with_data(|element| {
if let Some(ref webrender_api) = self.webrender_api { let size = self.drawtarget.get_size();
let size = self.drawtarget.get_size(); self.webrender_api.update_image(self.webrender_image_key,
webrender_api.update_image(self.webrender_image_key.unwrap(), size.width as u32,
size.width as u32, size.height as u32,
size.height as u32, webrender_traits::ImageFormat::RGBA8,
webrender_traits::ImageFormat::RGBA8, element.into());
element.into());
}
let pixel_data = CanvasPixelData { let pixel_data = CanvasPixelData {
image_data: IpcSharedMemory::from_bytes(element), image_data: IpcSharedMemory::from_bytes(element),
@ -710,9 +708,7 @@ impl<'a> CanvasPaintThread<'a> {
impl<'a> Drop for CanvasPaintThread<'a> { impl<'a> Drop for CanvasPaintThread<'a> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(ref mut wr) = self.webrender_api { self.webrender_api.delete_image(self.webrender_image_key);
wr.delete_image(self.webrender_image_key.unwrap());
}
} }
} }

View file

@ -87,7 +87,7 @@ impl GLContextWrapper {
enum WebGLPaintTaskData { enum WebGLPaintTaskData {
WebRender(webrender_traits::RenderApi, webrender_traits::WebGLContextId), WebRender(webrender_traits::RenderApi, webrender_traits::WebGLContextId),
Readback(GLContextWrapper, (Option<(webrender_traits::RenderApi, webrender_traits::ImageKey)>)), Readback(GLContextWrapper, webrender_traits::RenderApi, webrender_traits::ImageKey),
} }
pub struct WebGLPaintThread { pub struct WebGLPaintThread {
@ -97,17 +97,14 @@ pub struct WebGLPaintThread {
fn create_readback_painter(size: Size2D<i32>, fn create_readback_painter(size: Size2D<i32>,
attrs: GLContextAttributes, attrs: GLContextAttributes,
webrender_api: Option<webrender_traits::RenderApi>) webrender_api: webrender_traits::RenderApi)
-> Result<(WebGLPaintThread, GLLimits), String> { -> Result<(WebGLPaintThread, GLLimits), String> {
let context = try!(GLContextWrapper::new(size, attrs)); let context = try!(GLContextWrapper::new(size, attrs));
let limits = context.get_limits(); let limits = context.get_limits();
let webrender_api_and_image_key = webrender_api.map(|wr| { let image_key = webrender_api.alloc_image();
let key = wr.alloc_image();
(wr, key)
});
let painter = WebGLPaintThread { let painter = WebGLPaintThread {
size: size, size: size,
data: WebGLPaintTaskData::Readback(context, webrender_api_and_image_key) data: WebGLPaintTaskData::Readback(context, webrender_api, image_key)
}; };
Ok((painter, limits)) Ok((painter, limits))
@ -116,25 +113,21 @@ fn create_readback_painter(size: Size2D<i32>,
impl WebGLPaintThread { impl WebGLPaintThread {
fn new(size: Size2D<i32>, fn new(size: Size2D<i32>,
attrs: GLContextAttributes, attrs: GLContextAttributes,
webrender_api_sender: Option<webrender_traits::RenderApiSender>) webrender_api_sender: webrender_traits::RenderApiSender)
-> Result<(WebGLPaintThread, GLLimits), String> { -> Result<(WebGLPaintThread, GLLimits), String> {
if let Some(sender) = webrender_api_sender { let wr_api = webrender_api_sender.create_api();
let wr_api = sender.create_api(); match wr_api.request_webgl_context(&size, attrs) {
match wr_api.request_webgl_context(&size, attrs) { Ok((id, limits)) => {
Ok((id, limits)) => { let painter = WebGLPaintThread {
let painter = WebGLPaintThread { data: WebGLPaintTaskData::WebRender(wr_api, id),
data: WebGLPaintTaskData::WebRender(wr_api, id), size: size
size: size };
}; Ok((painter, limits))
Ok((painter, limits)) },
}, Err(msg) => {
Err(msg) => { warn!("Initial context creation failed, falling back to readback: {}", msg);
warn!("Initial context creation failed, falling back to readback: {}", msg); create_readback_painter(size, attrs, wr_api)
create_readback_painter(size, attrs, Some(wr_api))
}
} }
} else {
create_readback_painter(size, attrs, None)
} }
} }
@ -144,7 +137,7 @@ impl WebGLPaintThread {
WebGLPaintTaskData::WebRender(ref api, id) => { WebGLPaintTaskData::WebRender(ref api, id) => {
api.send_webgl_command(id, message); api.send_webgl_command(id, message);
} }
WebGLPaintTaskData::Readback(ref ctx, _) => { WebGLPaintTaskData::Readback(ref ctx, _, _) => {
ctx.apply_command(message); ctx.apply_command(message);
} }
} }
@ -154,7 +147,7 @@ impl WebGLPaintThread {
/// communicate with it. /// communicate with it.
pub fn start(size: Size2D<i32>, pub fn start(size: Size2D<i32>,
attrs: GLContextAttributes, attrs: GLContextAttributes,
webrender_api_sender: Option<webrender_traits::RenderApiSender>) webrender_api_sender: webrender_traits::RenderApiSender)
-> Result<(IpcSender<CanvasMsg>, GLLimits), String> { -> Result<(IpcSender<CanvasMsg>, GLLimits), String> {
let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap(); let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap();
let (result_chan, result_port) = channel(); let (result_chan, result_port) = channel();
@ -196,7 +189,7 @@ impl WebGLPaintThread {
fn send_data(&mut self, chan: IpcSender<CanvasData>) { fn send_data(&mut self, chan: IpcSender<CanvasData>) {
match self.data { match self.data {
WebGLPaintTaskData::Readback(_, ref webrender_api_and_image_key) => { WebGLPaintTaskData::Readback(_, ref webrender_api, image_key) => {
let width = self.size.width as usize; let width = self.size.width as usize;
let height = self.size.height as usize; let height = self.size.height as usize;
@ -217,19 +210,17 @@ impl WebGLPaintThread {
// rgba -> bgra // rgba -> bgra
byte_swap(&mut pixels); byte_swap(&mut pixels);
if let Some((ref wr, wr_image_key)) = *webrender_api_and_image_key { // TODO: This shouldn't be a common path, but try to avoid
// TODO: This shouldn't be a common path, but try to avoid // the spurious clone().
// the spurious clone(). webrender_api.update_image(image_key,
wr.update_image(wr_image_key, width as u32,
width as u32, height as u32,
height as u32, webrender_traits::ImageFormat::RGBA8,
webrender_traits::ImageFormat::RGBA8, pixels.clone());
pixels.clone());
}
let pixel_data = CanvasPixelData { let pixel_data = CanvasPixelData {
image_data: IpcSharedMemory::from_bytes(&pixels[..]), image_data: IpcSharedMemory::from_bytes(&pixels[..]),
image_key: webrender_api_and_image_key.as_ref().map(|&(_, key)| key), image_key: image_key,
}; };
chan.send(CanvasData::Pixels(pixel_data)).unwrap(); chan.send(CanvasData::Pixels(pixel_data)).unwrap();
@ -243,7 +234,7 @@ impl WebGLPaintThread {
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn recreate(&mut self, size: Size2D<i32>) -> Result<(), &'static str> { fn recreate(&mut self, size: Size2D<i32>) -> Result<(), &'static str> {
match self.data { match self.data {
WebGLPaintTaskData::Readback(ref mut context, _) => { WebGLPaintTaskData::Readback(ref mut context, _, _) => {
if size.width > self.size.width || if size.width > self.size.width ||
size.height > self.size.height { size.height > self.size.height {
self.size = try!(context.resize(size)); self.size = try!(context.resize(size));
@ -261,7 +252,7 @@ impl WebGLPaintThread {
} }
fn init(&mut self) { fn init(&mut self) {
if let WebGLPaintTaskData::Readback(ref context, _) = self.data { if let WebGLPaintTaskData::Readback(ref context, _, _) = self.data {
context.make_current(); context.make_current();
} }
} }
@ -269,7 +260,7 @@ impl WebGLPaintThread {
impl Drop for WebGLPaintThread { impl Drop for WebGLPaintThread {
fn drop(&mut self) { fn drop(&mut self) {
if let WebGLPaintTaskData::Readback(_, Some((ref mut wr, image_key))) = self.data { if let WebGLPaintTaskData::Readback(_, ref mut wr, image_key) = self.data {
wr.delete_image(image_key); wr.delete_image(image_key);
} }
} }

View file

@ -69,7 +69,7 @@ pub enum CanvasData {
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Deserialize, Serialize)]
pub struct CanvasPixelData { pub struct CanvasPixelData {
pub image_data: IpcSharedMemory, pub image_data: IpcSharedMemory,
pub image_key: Option<webrender_traits::ImageKey>, pub image_key: webrender_traits::ImageKey,
} }
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Deserialize, Serialize)]

View file

@ -10,14 +10,11 @@ name = "compositing"
path = "lib.rs" path = "lib.rs"
[dependencies] [dependencies]
app_units = "0.3"
azure = {git = "https://github.com/servo/rust-azure", features = ["plugins"]}
euclid = "0.10.1" euclid = "0.10.1"
gfx_traits = {path = "../gfx_traits"} gfx_traits = {path = "../gfx_traits"}
gleam = "0.2.8" gleam = "0.2.8"
image = "0.10" image = "0.10"
ipc-channel = "0.5" ipc-channel = "0.5"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
log = "0.3.5" log = "0.3.5"
msg = {path = "../msg"} msg = {path = "../msg"}
net_traits = {path = "../net_traits"} net_traits = {path = "../net_traits"}

File diff suppressed because it is too large Load diff

View file

@ -1,542 +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/. */
use azure::azure_hl;
use compositor::IOCompositor;
use euclid::point::TypedPoint2D;
use euclid::rect::TypedRect;
use euclid::size::TypedSize2D;
use gfx_traits::{Epoch, LayerId, LayerProperties, ScrollPolicy};
use layers::color::Color;
use layers::geometry::LayerPixel;
use layers::layers::{Layer, LayerBufferSet};
use msg::constellation_msg::PipelineId;
use script_traits::CompositorEvent;
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent, TouchpadPressureEvent};
use script_traits::ConstellationControlMsg;
use script_traits::MouseEventType;
use script_traits::TouchpadPressurePhase;
use std::rc::Rc;
use windowing::{MouseWindowEvent, WindowMethods};
#[derive(Debug)]
pub struct CompositorData {
/// This layer's pipeline id. The compositor can associate this id with an
/// actual CompositionPipeline.
pub pipeline_id: PipelineId,
/// The ID of this layer within the pipeline.
pub id: LayerId,
/// The behavior of this layer when a scroll message is received.
pub wants_scroll_events: WantsScrollEventsFlag,
/// Whether an ancestor layer that receives scroll events moves this layer.
pub scroll_policy: ScrollPolicy,
/// The epoch that has been requested for this layer (via send_buffer_requests).
pub requested_epoch: Epoch,
/// The last accepted painted buffer for this layer (via assign_pained_buffers).
pub painted_epoch: Epoch,
/// The scroll offset originating from this scrolling root. This allows scrolling roots
/// to track their current scroll position even while their content_offset does not change.
pub scroll_offset: TypedPoint2D<f32, LayerPixel>,
/// The pipeline ID of this layer, if it represents a subpage.
pub subpage_info: Option<PipelineId>,
}
impl CompositorData {
pub fn new_layer(pipeline_id: PipelineId,
layer_properties: LayerProperties,
wants_scroll_events: WantsScrollEventsFlag,
tile_size: usize)
-> Rc<Layer<CompositorData>> {
let new_compositor_data = CompositorData {
pipeline_id: pipeline_id,
id: layer_properties.id,
wants_scroll_events: wants_scroll_events,
scroll_policy: layer_properties.scroll_policy,
requested_epoch: Epoch(0),
painted_epoch: Epoch(0),
scroll_offset: TypedPoint2D::zero(),
subpage_info: layer_properties.subpage_pipeline_id,
};
Rc::new(Layer::new(TypedRect::from_untyped(&layer_properties.rect),
tile_size,
to_layers_color(&layer_properties.background_color),
1.0,
layer_properties.establishes_3d_context,
new_compositor_data))
}
}
pub trait CompositorLayer {
fn update_layer_except_bounds(&self, layer_properties: LayerProperties);
fn update_layer(&self, layer_properties: LayerProperties);
fn add_buffers<Window>(&self,
compositor: &mut IOCompositor<Window>,
new_buffers: Box<LayerBufferSet>,
epoch: Epoch)
where Window: WindowMethods;
/// Destroys all layer tiles, sending the buffers back to the painter to be destroyed or
/// reused.
fn clear<Window>(&self, compositor: &mut IOCompositor<Window>) where Window: WindowMethods;
/// Destroys tiles for this layer and all descendent layers, sending the buffers back to the
/// painter to be destroyed or reused.
fn clear_all_tiles<Window>(&self, compositor: &mut IOCompositor<Window>)
where Window: WindowMethods;
/// Removes the root layer (and any children) for a given pipeline from the
/// compositor. Buffers that the compositor is holding are returned to the
/// owning paint thread.
fn remove_root_layer_with_pipeline_id<Window>(&self,
compositor: &mut IOCompositor<Window>,
pipeline_id: PipelineId)
where Window: WindowMethods;
/// Destroys all tiles of all layers, including children, *without* sending them back to the
/// painter. You must call this only when the paint thread is destined to be going down;
/// otherwise, you will leak tiles.
///
/// This is used during shutdown, when we know the paint thread is going away.
fn forget_all_tiles(&self);
/// Move the layer's descendants that don't want scroll events and scroll by a relative
/// specified amount in page coordinates. This also takes in a cursor position to see if the
/// mouse is over child layers first. If a layer successfully scrolled returns either
/// ScrollPositionUnchanged or ScrollPositionChanged. If no layer was targeted by the event
/// returns ScrollEventUnhandled.
fn handle_scroll_event(&self,
delta: TypedPoint2D<f32, LayerPixel>,
cursor: TypedPoint2D<f32, LayerPixel>)
-> ScrollEventResult;
// Takes in a MouseWindowEvent, determines if it should be passed to children, and
// sends the event off to the appropriate pipeline. NB: the cursor position is in
// client coordinates.
fn send_mouse_event<Window>(&self,
compositor: &IOCompositor<Window>,
event: MouseWindowEvent,
cursor: TypedPoint2D<f32, LayerPixel>)
where Window: WindowMethods;
fn send_mouse_move_event<Window>(&self,
compositor: &IOCompositor<Window>,
cursor: TypedPoint2D<f32, LayerPixel>)
where Window: WindowMethods;
fn send_event<Window>(&self,
compositor: &IOCompositor<Window>,
event: CompositorEvent)
where Window: WindowMethods;
fn send_touchpad_pressure_event<Window>(&self,
compositor: &IOCompositor<Window>,
cursor: TypedPoint2D<f32, LayerPixel>,
pressure: f32,
phase: TouchpadPressurePhase)
where Window: WindowMethods;
fn clamp_scroll_offset_and_scroll_layer(&self,
new_offset: TypedPoint2D<f32, LayerPixel>)
-> ScrollEventResult;
fn scroll_layer_and_all_child_layers(&self,
new_offset: TypedPoint2D<f32, LayerPixel>)
-> bool;
/// Return a flag describing how this layer deals with scroll events.
fn wants_scroll_events(&self) -> WantsScrollEventsFlag;
/// Return the pipeline id associated with this layer.
fn pipeline_id(&self) -> PipelineId;
}
pub trait RcCompositorLayer {
/// Traverses the existing layer hierarchy and removes any layers that
/// currently exist but which are no longer required.
fn collect_old_layers<Window>(&self,
compositor: &mut IOCompositor<Window>,
pipeline_id: PipelineId,
new_layers: &[LayerProperties],
pipelines_removed: &mut Vec<PipelineId>)
where Window: WindowMethods;
}
#[derive(Copy, PartialEq, Clone, Debug)]
pub enum WantsScrollEventsFlag {
WantsScrollEvents,
DoesntWantScrollEvents,
}
fn to_layers_color(color: &azure_hl::Color) -> Color {
Color { r: color.r, g: color.g, b: color.b, a: color.a }
}
trait Clampable {
fn clamp(&self, mn: &Self, mx: &Self) -> Self;
}
impl Clampable for f32 {
/// Returns the number constrained within the range `mn <= self <= mx`.
/// If any of the numbers are `NAN` then `NAN` is returned.
#[inline]
fn clamp(&self, mn: &f32, mx: &f32) -> f32 {
match () {
_ if self.is_nan() => *self,
_ if !(*self <= *mx) => *mx,
_ if !(*self >= *mn) => *mn,
_ => *self,
}
}
}
fn calculate_content_size_for_layer(layer: &Layer<CompositorData>)
-> TypedSize2D<f32, LayerPixel> {
layer.children().iter().fold(TypedRect::zero(),
|unioned_rect, child_rect| {
unioned_rect.union(&*child_rect.bounds.borrow())
}).size
}
#[derive(PartialEq)]
pub enum ScrollEventResult {
ScrollEventUnhandled,
ScrollPositionChanged,
ScrollPositionUnchanged,
}
impl CompositorLayer for Layer<CompositorData> {
fn update_layer_except_bounds(&self, layer_properties: LayerProperties) {
self.extra_data.borrow_mut().scroll_policy = layer_properties.scroll_policy;
self.extra_data.borrow_mut().subpage_info = layer_properties.subpage_pipeline_id;
*self.transform.borrow_mut() = layer_properties.transform;
*self.perspective.borrow_mut() = layer_properties.perspective;
*self.background_color.borrow_mut() = to_layers_color(&layer_properties.background_color);
self.contents_changed();
}
fn update_layer(&self, layer_properties: LayerProperties) {
*self.bounds.borrow_mut() = TypedRect::from_untyped(&layer_properties.rect);
// Call scroll for bounds checking if the page shrunk. Use (-1, -1) as the
// cursor position to make sure the scroll isn't propagated downwards.
self.handle_scroll_event(TypedPoint2D::zero(), TypedPoint2D::new(-1f32, -1f32));
self.update_layer_except_bounds(layer_properties);
}
// Add LayerBuffers to the specified layer. Returns the layer buffer set back if the layer that
// matches the given pipeline ID was not found; otherwise returns None and consumes the layer
// buffer set.
//
// If the epoch of the message does not match the layer's epoch, the message is ignored, the
// layer buffer set is consumed, and None is returned.
fn add_buffers<Window>(&self,
compositor: &mut IOCompositor<Window>,
new_buffers: Box<LayerBufferSet>,
epoch: Epoch)
where Window: WindowMethods {
self.extra_data.borrow_mut().painted_epoch = epoch;
assert!(self.extra_data.borrow().painted_epoch == self.extra_data.borrow().requested_epoch);
for buffer in new_buffers.buffers.into_iter().rev() {
self.add_buffer(buffer);
}
compositor.cache_unused_buffers(self.collect_unused_buffers())
}
fn clear<Window>(&self, compositor: &mut IOCompositor<Window>) where Window: WindowMethods {
let buffers = self.collect_buffers();
if !buffers.is_empty() {
compositor.cache_unused_buffers(buffers);
}
}
/// Destroys tiles for this layer and all descendent layers, sending the buffers back to the
/// painter to be destroyed or reused.
fn clear_all_tiles<Window>(&self,
compositor: &mut IOCompositor<Window>)
where Window: WindowMethods {
self.clear(compositor);
for kid in &*self.children() {
kid.clear_all_tiles(compositor);
}
}
fn remove_root_layer_with_pipeline_id<Window>(&self,
compositor: &mut IOCompositor<Window>,
pipeline_id: PipelineId)
where Window: WindowMethods {
// Find the child that is the root layer for this pipeline.
let index = self.children().iter().position(|kid| {
let extra_data = kid.extra_data.borrow();
extra_data.pipeline_id == pipeline_id && extra_data.id == LayerId::null()
});
match index {
Some(index) => {
// Remove the root layer, and return buffers to the paint thread
let child = self.children().remove(index);
child.clear_all_tiles(compositor);
}
None => {
// Wasn't found, recurse into child layers
for kid in &*self.children() {
kid.remove_root_layer_with_pipeline_id(compositor, pipeline_id);
}
}
}
}
/// Destroys all tiles of all layers, including children, *without* sending them back to the
/// painter. You must call this only when the paint thread is destined to be going down;
/// otherwise, you will leak tiles.
///
/// This is used during shutdown, when we know the paint thread is going away.
fn forget_all_tiles(&self) {
let tiles = self.collect_buffers();
for tile in tiles {
let mut tile = tile;
tile.mark_wont_leak()
}
for kid in &*self.children() {
kid.forget_all_tiles();
}
}
fn handle_scroll_event(&self,
delta: TypedPoint2D<f32, LayerPixel>,
cursor: TypedPoint2D<f32, LayerPixel>)
-> ScrollEventResult {
// Allow children to scroll.
let scroll_offset = self.extra_data.borrow().scroll_offset;
let new_cursor = cursor - scroll_offset;
for child in self.children().iter().rev() {
let child_bounds = child.bounds.borrow();
if child_bounds.contains(&new_cursor) {
let result = child.handle_scroll_event(delta, new_cursor - child_bounds.origin);
if result != ScrollEventResult::ScrollEventUnhandled {
return result;
}
}
}
// If this layer doesn't want scroll events, it can't handle scroll events.
if self.wants_scroll_events() != WantsScrollEventsFlag::WantsScrollEvents {
return ScrollEventResult::ScrollEventUnhandled;
}
self.clamp_scroll_offset_and_scroll_layer(scroll_offset + delta)
}
fn clamp_scroll_offset_and_scroll_layer(&self, new_offset: TypedPoint2D<f32, LayerPixel>)
-> ScrollEventResult {
let layer_size = self.bounds.borrow().size;
let content_size = calculate_content_size_for_layer(self);
let min_x = (layer_size.width - content_size.width).min(0.0);
let min_y = (layer_size.height - content_size.height).min(0.0);
let new_offset: TypedPoint2D<f32, LayerPixel> =
TypedPoint2D::new(new_offset.x.clamp(&min_x, &0.0),
new_offset.y.clamp(&min_y, &0.0));
if self.extra_data.borrow().scroll_offset == new_offset {
return ScrollEventResult::ScrollPositionUnchanged;
}
// The scroll offset is just a record of the scroll position of this scrolling root,
// but scroll_layer_and_all_child_layers actually moves the child layers.
self.extra_data.borrow_mut().scroll_offset = new_offset;
let mut result = false;
for child in &*self.children() {
result |= child.scroll_layer_and_all_child_layers(new_offset);
}
if result {
ScrollEventResult::ScrollPositionChanged
} else {
ScrollEventResult::ScrollPositionUnchanged
}
}
fn send_mouse_event<Window>(&self,
compositor: &IOCompositor<Window>,
event: MouseWindowEvent,
cursor: TypedPoint2D<f32, LayerPixel>)
where Window: WindowMethods {
let event_point = cursor.to_untyped();
let message = match event {
MouseWindowEvent::Click(button, _) =>
MouseButtonEvent(MouseEventType::Click, button, event_point),
MouseWindowEvent::MouseDown(button, _) =>
MouseButtonEvent(MouseEventType::MouseDown, button, event_point),
MouseWindowEvent::MouseUp(button, _) =>
MouseButtonEvent(MouseEventType::MouseUp, button, event_point),
};
self.send_event(compositor, message);
}
fn send_mouse_move_event<Window>(&self,
compositor: &IOCompositor<Window>,
cursor: TypedPoint2D<f32, LayerPixel>)
where Window: WindowMethods {
self.send_event(compositor, MouseMoveEvent(Some(cursor.to_untyped())));
}
fn send_event<Window>(&self,
compositor: &IOCompositor<Window>,
event: CompositorEvent) where Window: WindowMethods {
if let Some(pipeline) = compositor.pipeline(self.pipeline_id()) {
let _ = pipeline.script_chan
.send(ConstellationControlMsg::SendEvent(pipeline.id.clone(), event));
}
}
fn send_touchpad_pressure_event<Window>(&self,
compositor: &IOCompositor<Window>,
cursor: TypedPoint2D<f32, LayerPixel>,
pressure: f32,
phase: TouchpadPressurePhase)
where Window: WindowMethods {
if let Some(pipeline) = compositor.pipeline(self.pipeline_id()) {
let message = TouchpadPressureEvent(cursor.to_untyped(), pressure, phase);
let _ = pipeline.script_chan.send(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
}
}
fn scroll_layer_and_all_child_layers(&self, new_offset: TypedPoint2D<f32, LayerPixel>)
-> bool {
let mut result = false;
// Only scroll this layer if it's not fixed-positioned.
if self.extra_data.borrow().scroll_policy != ScrollPolicy::FixedPosition {
let new_offset = new_offset.to_untyped();
*self.content_offset.borrow_mut() = TypedPoint2D::from_untyped(&new_offset);
result = true
}
let offset_for_children = new_offset + self.extra_data.borrow().scroll_offset;
for child in &*self.children() {
result |= child.scroll_layer_and_all_child_layers(offset_for_children);
}
result
}
fn wants_scroll_events(&self) -> WantsScrollEventsFlag {
self.extra_data.borrow().wants_scroll_events
}
fn pipeline_id(&self) -> PipelineId {
self.extra_data.borrow().pipeline_id
}
}
impl RcCompositorLayer for Rc<Layer<CompositorData>> {
fn collect_old_layers<Window>(&self,
compositor: &mut IOCompositor<Window>,
pipeline_id: PipelineId,
new_layers: &[LayerProperties],
pipelines_removed: &mut Vec<PipelineId>)
where Window: WindowMethods {
fn find_root_layer_for_pipeline(layer: &Rc<Layer<CompositorData>>, pipeline_id: PipelineId)
-> Option<Rc<Layer<CompositorData>>> {
let extra_data = layer.extra_data.borrow();
if extra_data.pipeline_id == pipeline_id {
return Some((*layer).clone())
}
for kid in &*layer.children() {
if let Some(layer) = find_root_layer_for_pipeline(kid, pipeline_id) {
return Some(layer.clone())
}
}
None
}
fn collect_old_layers_for_pipeline<Window>(
layer: &Layer<CompositorData>,
compositor: &mut IOCompositor<Window>,
pipeline_id: PipelineId,
new_layers: &[LayerProperties],
pipelines_removed: &mut Vec<PipelineId>,
layer_pipeline_id: Option<PipelineId>)
where Window: WindowMethods {
// Traverse children first so that layers are removed
// bottom up - allowing each layer being removed to properly
// clean up any tiles it owns.
for kid in &*layer.children() {
let extra_data = kid.extra_data.borrow();
let layer_pipeline_id = extra_data.subpage_info.or(layer_pipeline_id);
collect_old_layers_for_pipeline(kid,
compositor,
pipeline_id,
new_layers,
pipelines_removed,
layer_pipeline_id);
}
// Retain child layers that also exist in the new layer list.
layer.children().retain(|child| {
let extra_data = child.extra_data.borrow();
if pipeline_id == extra_data.pipeline_id {
// Never remove our own root layer.
if extra_data.id == LayerId::null() {
return true
}
// Keep this layer if it exists in the new layer list.
if new_layers.iter().any(|properties| properties.id == extra_data.id) {
return true
}
}
if let Some(layer_pipeline_id) = layer_pipeline_id {
for layer_properties in new_layers.iter() {
// Keep this layer if a reference to it exists.
if let Some(ref subpage_pipeline_id) = layer_properties.subpage_pipeline_id {
if *subpage_pipeline_id == layer_pipeline_id {
return true
}
}
}
pipelines_removed.push(extra_data.pipeline_id);
}
// When removing a layer, clear any tiles and surfaces associated with the layer.
child.clear_all_tiles(compositor);
false
});
}
// First, find the root layer with the given pipeline ID.
let root_layer = match find_root_layer_for_pipeline(self, pipeline_id) {
Some(root_layer) => root_layer,
None => return,
};
// Then collect all old layers underneath that layer.
collect_old_layers_for_pipeline(&root_layer,
compositor,
pipeline_id,
new_layers,
pipelines_removed,
None);
}
}

View file

@ -8,16 +8,14 @@ use SendableFrameTree;
use compositor::CompositingReason; use compositor::CompositingReason;
use euclid::point::Point2D; use euclid::point::Point2D;
use euclid::size::Size2D; use euclid::size::Size2D;
use gfx_traits::{Epoch, FrameTreeId, LayerId, LayerProperties, PaintListener}; use gfx_traits::LayerId;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use layers::layers::{BufferRequest, LayerBufferSet};
use layers::platform::surface::{NativeDisplay, NativeSurface};
use msg::constellation_msg::{Image, Key, KeyModifiers, KeyState, PipelineId}; use msg::constellation_msg::{Image, Key, KeyModifiers, KeyState, PipelineId};
use profile_traits::mem; use profile_traits::mem;
use profile_traits::time; use profile_traits::time;
use script_traits::{AnimationState, ConstellationMsg, EventResult}; use script_traits::{AnimationState, ConstellationMsg, EventResult};
use std::fmt::{Debug, Error, Formatter}; use std::fmt::{Debug, Error, Formatter};
use std::sync::mpsc::{Receiver, Sender, channel}; use std::sync::mpsc::{Receiver, Sender};
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use url::Url; use url::Url;
@ -63,55 +61,6 @@ impl RenderListener for Box<CompositorProxy + 'static> {
} }
} }
/// Implementation of the abstract `PaintListener` interface.
impl PaintListener for Box<CompositorProxy + 'static + Send> {
fn native_display(&mut self) -> Option<NativeDisplay> {
let (chan, port) = channel();
self.send(Msg::GetNativeDisplay(chan));
// If the compositor is shutting down when a paint thread
// is being created, the compositor won't respond to
// this message, resulting in an eventual panic. Instead,
// just return None in this case, since the paint thread
// will exit shortly and never actually be requested
// to paint buffers by the compositor.
port.recv().unwrap_or(None)
}
fn assign_painted_buffers(&mut self,
pipeline_id: PipelineId,
epoch: Epoch,
replies: Vec<(LayerId, Box<LayerBufferSet>)>,
frame_tree_id: FrameTreeId) {
self.send(Msg::AssignPaintedBuffers(pipeline_id, epoch, replies, frame_tree_id));
}
fn ignore_buffer_requests(&mut self, buffer_requests: Vec<BufferRequest>) {
let mut native_surfaces = Vec::new();
for request in buffer_requests.into_iter() {
if let Some(native_surface) = request.native_surface {
native_surfaces.push(native_surface);
}
}
if !native_surfaces.is_empty() {
self.send(Msg::ReturnUnusedNativeSurfaces(native_surfaces));
}
}
fn initialize_layers_for_pipeline(&mut self,
pipeline_id: PipelineId,
properties: Vec<LayerProperties>,
epoch: Epoch) {
// FIXME(#2004, pcwalton): This assumes that the first layer determines the page size, and
// that all other layers are immediate children of it. This is sufficient to handle
// `position: fixed` but will not be sufficient to handle `overflow: scroll` or transforms.
self.send(Msg::InitializeLayersForPipeline(pipeline_id, epoch, properties));
}
fn notify_paint_thread_exiting(&mut self, pipeline_id: PipelineId) {
self.send(Msg::PaintThreadExited(pipeline_id))
}
}
/// Messages from the painting thread and the constellation thread to the compositor thread. /// Messages from the painting thread and the constellation thread to the compositor thread.
pub enum Msg { pub enum Msg {
/// Requests that the compositor shut down. /// Requests that the compositor shut down.
@ -122,18 +71,8 @@ pub enum Msg {
/// (e.g. SetFrameTree) at the time that we send it an ExitMsg. /// (e.g. SetFrameTree) at the time that we send it an ExitMsg.
ShutdownComplete, ShutdownComplete,
/// Requests the compositor's graphics metadata. Graphics metadata is what the painter needs
/// to create surfaces that the compositor can see. On Linux this is the X display; on Mac this
/// is the pixel format.
GetNativeDisplay(Sender<Option<NativeDisplay>>),
/// Tells the compositor to create or update the layers for a pipeline if necessary
/// (i.e. if no layer with that ID exists).
InitializeLayersForPipeline(PipelineId, Epoch, Vec<LayerProperties>),
/// Scroll a page in a window /// Scroll a page in a window
ScrollFragmentPoint(PipelineId, LayerId, Point2D<f32>, bool), ScrollFragmentPoint(PipelineId, LayerId, Point2D<f32>, bool),
/// Requests that the compositor assign the painted buffers to the given layers.
AssignPaintedBuffers(PipelineId, Epoch, Vec<(LayerId, Box<LayerBufferSet>)>, FrameTreeId),
/// Alerts the compositor that the current page has changed its title. /// Alerts the compositor that the current page has changed its title.
ChangePageTitle(PipelineId, Option<String>), ChangePageTitle(PipelineId, Option<String>),
/// Alerts the compositor that the current page has changed its URL. /// Alerts the compositor that the current page has changed its URL.
@ -158,8 +97,6 @@ pub enum Msg {
SetCursor(Cursor), SetCursor(Cursor),
/// Composite to a PNG file and return the Image over a passed channel. /// Composite to a PNG file and return the Image over a passed channel.
CreatePng(IpcSender<Option<Image>>), CreatePng(IpcSender<Option<Image>>),
/// Informs the compositor that the paint thread for the given pipeline has exited.
PaintThreadExited(PipelineId),
/// Alerts the compositor that the viewport has been constrained in some manner /// Alerts the compositor that the viewport has been constrained in some manner
ViewportConstrained(PipelineId, ViewportConstraints), ViewportConstrained(PipelineId, ViewportConstraints),
/// A reply to the compositor asking if the output image is stable. /// A reply to the compositor asking if the output image is stable.
@ -168,9 +105,6 @@ pub enum Msg {
NewFavicon(Url), NewFavicon(Url),
/// <head> tag finished parsing /// <head> tag finished parsing
HeadParsed, HeadParsed,
/// Signal that the paint thread ignored the paint requests that carried
/// these native surfaces, so that they can be re-added to the surface cache.
ReturnUnusedNativeSurfaces(Vec<NativeSurface>),
/// Collect memory reports and send them back to the given mem::ReportsChan. /// Collect memory reports and send them back to the given mem::ReportsChan.
CollectMemoryReports(mem::ReportsChan), CollectMemoryReports(mem::ReportsChan),
/// A status message to be displayed by the browser chrome. /// A status message to be displayed by the browser chrome.
@ -181,8 +115,6 @@ pub enum Msg {
MoveTo(Point2D<i32>), MoveTo(Point2D<i32>),
/// Resize the window to size /// Resize the window to size
ResizeTo(Size2D<u32>), ResizeTo(Size2D<u32>),
/// Get scroll offset of a layer
GetScrollOffset(PipelineId, LayerId, IpcSender<Point2D<f32>>),
/// Pipeline visibility changed /// Pipeline visibility changed
PipelineVisibilityChanged(PipelineId, bool), PipelineVisibilityChanged(PipelineId, bool),
/// WebRender has successfully processed a scroll. The boolean specifies whether a composite is /// WebRender has successfully processed a scroll. The boolean specifies whether a composite is
@ -201,10 +133,7 @@ impl Debug for Msg {
match *self { match *self {
Msg::Exit => write!(f, "Exit"), Msg::Exit => write!(f, "Exit"),
Msg::ShutdownComplete => write!(f, "ShutdownComplete"), Msg::ShutdownComplete => write!(f, "ShutdownComplete"),
Msg::GetNativeDisplay(..) => write!(f, "GetNativeDisplay"),
Msg::InitializeLayersForPipeline(..) => write!(f, "InitializeLayersForPipeline"),
Msg::ScrollFragmentPoint(..) => write!(f, "ScrollFragmentPoint"), Msg::ScrollFragmentPoint(..) => write!(f, "ScrollFragmentPoint"),
Msg::AssignPaintedBuffers(..) => write!(f, "AssignPaintedBuffers"),
Msg::ChangeRunningAnimationsState(..) => write!(f, "ChangeRunningAnimationsState"), Msg::ChangeRunningAnimationsState(..) => write!(f, "ChangeRunningAnimationsState"),
Msg::ChangePageTitle(..) => write!(f, "ChangePageTitle"), Msg::ChangePageTitle(..) => write!(f, "ChangePageTitle"),
Msg::ChangePageUrl(..) => write!(f, "ChangePageUrl"), Msg::ChangePageUrl(..) => write!(f, "ChangePageUrl"),
@ -217,12 +146,10 @@ impl Debug for Msg {
Msg::TouchEventProcessed(..) => write!(f, "TouchEventProcessed"), Msg::TouchEventProcessed(..) => write!(f, "TouchEventProcessed"),
Msg::SetCursor(..) => write!(f, "SetCursor"), Msg::SetCursor(..) => write!(f, "SetCursor"),
Msg::CreatePng(..) => write!(f, "CreatePng"), Msg::CreatePng(..) => write!(f, "CreatePng"),
Msg::PaintThreadExited(..) => write!(f, "PaintThreadExited"),
Msg::ViewportConstrained(..) => write!(f, "ViewportConstrained"), Msg::ViewportConstrained(..) => write!(f, "ViewportConstrained"),
Msg::IsReadyToSaveImageReply(..) => write!(f, "IsReadyToSaveImageReply"), Msg::IsReadyToSaveImageReply(..) => write!(f, "IsReadyToSaveImageReply"),
Msg::NewFavicon(..) => write!(f, "NewFavicon"), Msg::NewFavicon(..) => write!(f, "NewFavicon"),
Msg::HeadParsed => write!(f, "HeadParsed"), Msg::HeadParsed => write!(f, "HeadParsed"),
Msg::ReturnUnusedNativeSurfaces(..) => write!(f, "ReturnUnusedNativeSurfaces"),
Msg::CollectMemoryReports(..) => write!(f, "CollectMemoryReports"), Msg::CollectMemoryReports(..) => write!(f, "CollectMemoryReports"),
Msg::Status(..) => write!(f, "Status"), Msg::Status(..) => write!(f, "Status"),
Msg::GetClientWindow(..) => write!(f, "GetClientWindow"), Msg::GetClientWindow(..) => write!(f, "GetClientWindow"),
@ -230,7 +157,6 @@ impl Debug for Msg {
Msg::ResizeTo(..) => write!(f, "ResizeTo"), Msg::ResizeTo(..) => write!(f, "ResizeTo"),
Msg::PipelineVisibilityChanged(..) => write!(f, "PipelineVisibilityChanged"), Msg::PipelineVisibilityChanged(..) => write!(f, "PipelineVisibilityChanged"),
Msg::PipelineExited(..) => write!(f, "PipelineExited"), Msg::PipelineExited(..) => write!(f, "PipelineExited"),
Msg::GetScrollOffset(..) => write!(f, "GetScrollOffset"),
Msg::NewScrollFrameReady(..) => write!(f, "NewScrollFrameReady"), Msg::NewScrollFrameReady(..) => write!(f, "NewScrollFrameReady"),
} }
} }
@ -248,7 +174,7 @@ pub struct InitialCompositorState {
pub time_profiler_chan: time::ProfilerChan, pub time_profiler_chan: time::ProfilerChan,
/// A channel to the memory profiler thread. /// A channel to the memory profiler thread.
pub mem_profiler_chan: mem::ProfilerChan, pub mem_profiler_chan: mem::ProfilerChan,
/// Instance of webrender API if enabled /// Instance of webrender API
pub webrender: Option<webrender::Renderer>, pub webrender: webrender::Renderer,
pub webrender_api_sender: Option<webrender_traits::RenderApiSender>, pub webrender_api_sender: webrender_traits::RenderApiSender,
} }

View file

@ -10,15 +10,11 @@
#![deny(unsafe_code)] #![deny(unsafe_code)]
extern crate app_units;
extern crate azure;
extern crate euclid; extern crate euclid;
extern crate gfx_traits; extern crate gfx_traits;
extern crate gleam; extern crate gleam;
extern crate image; extern crate image;
extern crate ipc_channel; extern crate ipc_channel;
extern crate layers;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate msg; extern crate msg;
@ -39,18 +35,14 @@ extern crate webrender_traits;
pub use compositor_thread::CompositorProxy; pub use compositor_thread::CompositorProxy;
pub use compositor::IOCompositor; pub use compositor::IOCompositor;
use euclid::size::TypedSize2D; use euclid::size::TypedSize2D;
use gfx_traits::ChromeToPaintMsg;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use script_traits::{ConstellationControlMsg, LayoutControlMsg}; use script_traits::{ConstellationControlMsg, LayoutControlMsg};
use std::sync::mpsc::Sender;
use style_traits::PagePx; use style_traits::PagePx;
mod compositor; mod compositor;
mod compositor_layer;
pub mod compositor_thread; pub mod compositor_thread;
mod delayed_composition; mod delayed_composition;
mod surface_map;
mod touch; mod touch;
pub mod windowing; pub mod windowing;
@ -66,5 +58,4 @@ pub struct CompositionPipeline {
pub id: PipelineId, pub id: PipelineId,
pub script_chan: IpcSender<ConstellationControlMsg>, pub script_chan: IpcSender<ConstellationControlMsg>,
pub layout_chan: IpcSender<LayoutControlMsg>, pub layout_chan: IpcSender<LayoutControlMsg>,
pub chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
} }

View file

@ -1,164 +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/. */
use euclid::size::Size2D;
use layers::platform::surface::{NativeDisplay, NativeSurface};
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::hash::{Hash, Hasher};
/// This is a struct used to store surfaces when they are not in use.
/// The paint thread can quickly query for a particular size of surface when it
/// needs it.
pub struct SurfaceMap {
/// A HashMap that stores the Buffers.
map: HashMap<SurfaceKey, SurfaceValue>,
/// The current amount of memory stored by the SurfaceMap's surfaces.
mem: usize,
/// The maximum allowed memory. Unused surfaces will be deleted
/// when this threshold is exceeded.
max_mem: usize,
/// A monotonically increasing counter to track how recently tile sizes were used.
counter: usize,
}
/// A key with which to store surfaces. It is based on the size of the surface.
#[derive(Eq, Copy, Clone)]
struct SurfaceKey([i32; 2]);
impl Hash for SurfaceKey {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl PartialEq for SurfaceKey {
fn eq(&self, other: &SurfaceKey) -> bool {
let SurfaceKey(s) = *self;
let SurfaceKey(o) = *other;
s[0] == o[0] && s[1] == o[1]
}
}
/// Create a key from a given size
impl SurfaceKey {
fn get(input: Size2D<i32>) -> SurfaceKey {
SurfaceKey([input.width, input.height])
}
}
/// A helper struct to keep track of surfaces in the HashMap
struct SurfaceValue {
/// An array of surfaces, all the same size
surfaces: Vec<NativeSurface>,
/// The counter when this size was last requested
last_action: usize,
}
impl SurfaceMap {
// Creates a new SurfaceMap with a given surface limit.
pub fn new(max_mem: usize) -> SurfaceMap {
SurfaceMap {
map: HashMap::new(),
mem: 0,
max_mem: max_mem,
counter: 0,
}
}
pub fn insert_surfaces<I>(&mut self, display: &NativeDisplay, surfaces: I)
where I: IntoIterator<Item=NativeSurface>
{
for surface in surfaces {
self.insert(display, surface);
}
}
/// Insert a new buffer into the map.
pub fn insert(&mut self, display: &NativeDisplay, mut new_surface: NativeSurface) {
let new_key = SurfaceKey::get(new_surface.get_size());
// If all our surfaces are the same size and we're already at our
// memory limit, no need to store this new buffer; just let it drop.
let new_total_memory_usage = self.mem + new_surface.get_memory_usage();
if new_total_memory_usage > self.max_mem && self.map.len() == 1 &&
self.map.contains_key(&new_key) {
new_surface.destroy(display);
return;
}
self.mem = new_total_memory_usage;
new_surface.mark_wont_leak();
// use lazy insertion function to prevent unnecessary allocation
let counter = &self.counter;
match self.map.entry(new_key) {
Occupied(entry) => {
entry.into_mut().surfaces.push(new_surface);
}
Vacant(entry) => {
entry.insert(SurfaceValue {
surfaces: vec!(new_surface),
last_action: *counter,
});
}
}
let mut opt_key: Option<SurfaceKey> = None;
while self.mem > self.max_mem {
let old_key = match opt_key {
Some(key) => key,
None => {
match self.map.iter().min_by_key(|&(_, x)| x.last_action) {
Some((k, _)) => *k,
None => panic!("SurfaceMap: tried to delete with no elements in map"),
}
}
};
if {
let list = &mut self.map.get_mut(&old_key).unwrap().surfaces;
let mut condemned_surface = list.pop().take().unwrap();
self.mem -= condemned_surface.get_memory_usage();
condemned_surface.destroy(display);
list.is_empty()
}
{ // then
self.map.remove(&old_key); // Don't store empty vectors!
opt_key = None;
} else {
opt_key = Some(old_key);
}
}
}
// Try to find a buffer for the given size.
pub fn find(&mut self, size: Size2D<i32>) -> Option<NativeSurface> {
let mut flag = false; // True if key needs to be popped after retrieval.
let key = SurfaceKey::get(size);
let ret = match self.map.get_mut(&key) {
Some(ref mut surface_val) => {
surface_val.last_action = self.counter;
self.counter += 1;
let surface = surface_val.surfaces.pop().take().unwrap();
self.mem -= surface.get_memory_usage();
if surface_val.surfaces.is_empty() {
flag = true;
}
Some(surface)
}
None => None,
};
if flag {
self.map.remove(&key); // Don't store empty vectors!
}
ret
}
pub fn mem(&self) -> usize {
self.mem
}
}

View file

@ -4,7 +4,7 @@
use euclid::point::TypedPoint2D; use euclid::point::TypedPoint2D;
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
use layers::geometry::DevicePixel; use gfx_traits::DevicePixel;
use script_traits::{EventResult, TouchId}; use script_traits::{EventResult, TouchId};
use self::TouchState::*; use self::TouchState::*;

View file

@ -9,8 +9,7 @@ use euclid::{Point2D, Size2D};
use euclid::point::TypedPoint2D; use euclid::point::TypedPoint2D;
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D; use euclid::size::TypedSize2D;
use layers::geometry::DevicePixel; use gfx_traits::DevicePixel;
use layers::platform::surface::NativeDisplay;
use msg::constellation_msg::{Key, KeyModifiers, KeyState}; use msg::constellation_msg::{Key, KeyModifiers, KeyState};
use net_traits::net_error_list::NetError; use net_traits::net_error_list::NetError;
use script_traits::{MouseButton, TouchEventType, TouchId, TouchpadPressurePhase}; use script_traits::{MouseButton, TouchEventType, TouchId, TouchpadPressurePhase};
@ -139,9 +138,6 @@ pub trait WindowMethods {
/// Returns the scale factor of the system (device pixels / screen pixels). /// Returns the scale factor of the system (device pixels / screen pixels).
fn scale_factor(&self) -> ScaleFactor<f32, ScreenPx, DevicePixel>; fn scale_factor(&self) -> ScaleFactor<f32, ScreenPx, DevicePixel>;
/// Gets the OS native graphics display for this window.
fn native_display(&self) -> NativeDisplay;
/// Creates a channel to the compositor. The dummy parameter is needed because we don't have /// Creates a channel to the compositor. The dummy parameter is needed because we don't have
/// UFCS in Rust yet. /// UFCS in Rust yet.
/// ///

View file

@ -19,7 +19,6 @@ euclid = "0.10.1"
gfx = {path = "../gfx"} gfx = {path = "../gfx"}
gfx_traits = {path = "../gfx_traits"} gfx_traits = {path = "../gfx_traits"}
ipc-channel = "0.5" ipc-channel = "0.5"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
layout_traits = {path = "../layout_traits"} layout_traits = {path = "../layout_traits"}
log = "0.3.5" log = "0.3.5"
msg = {path = "../msg"} msg = {path = "../msg"}

View file

@ -172,8 +172,8 @@ pub struct Constellation<Message, LTF, STF> {
/// Document states for loaded pipelines (used only when writing screenshots). /// Document states for loaded pipelines (used only when writing screenshots).
document_states: HashMap<PipelineId, DocumentState>, document_states: HashMap<PipelineId, DocumentState>,
// Webrender interface, if enabled. // Webrender interface.
webrender_api_sender: Option<webrender_traits::RenderApiSender>, webrender_api_sender: webrender_traits::RenderApiSender,
/// Are we shutting down? /// Are we shutting down?
shutting_down: bool, shutting_down: bool,
@ -209,8 +209,8 @@ pub struct InitialConstellationState {
pub mem_profiler_chan: mem::ProfilerChan, pub mem_profiler_chan: mem::ProfilerChan,
/// Whether the constellation supports the clipboard. /// Whether the constellation supports the clipboard.
pub supports_clipboard: bool, pub supports_clipboard: bool,
/// Optional webrender API reference (if enabled). /// Webrender API.
pub webrender_api_sender: Option<webrender_traits::RenderApiSender>, pub webrender_api_sender: webrender_traits::RenderApiSender,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -971,9 +971,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
self.compositor_proxy.send(ToCompositorMsg::TouchEventProcessed(result)) self.compositor_proxy.send(ToCompositorMsg::TouchEventProcessed(result))
} }
FromScriptMsg::GetScrollOffset(pid, lid, send) => {
self.compositor_proxy.send(ToCompositorMsg::GetScrollOffset(pid, lid, send));
}
FromScriptMsg::RegisterServiceWorker(scope_things, scope) => { FromScriptMsg::RegisterServiceWorker(scope_things, scope) => {
debug!("constellation got store registration scope message"); debug!("constellation got store registration scope message");
self.handle_register_serviceworker(scope_things, scope); self.handle_register_serviceworker(scope_things, scope);
@ -1852,8 +1849,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
} }
// Set paint permissions correctly for the compositor layers. // Set paint permissions correctly for the compositor layers.
self.revoke_paint_permission(prev_pipeline_id); self.send_frame_tree();
self.send_frame_tree_and_grant_paint_permission();
// Update the owning iframe to point to the new pipeline id. // Update the owning iframe to point to the new pipeline id.
// This makes things like contentDocument work correctly. // This makes things like contentDocument work correctly.
@ -1910,12 +1906,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
} }
} }
if let Some(old_pipeline_id) = frame_change.old_pipeline_id {
// The new pipeline is replacing an old one.
// Remove paint permissions for the pipeline being replaced.
self.revoke_paint_permission(old_pipeline_id);
};
if self.frames.contains_key(&frame_change.frame_id) { if self.frames.contains_key(&frame_change.frame_id) {
// Mature the new pipeline, and return frames evicted from history. // Mature the new pipeline, and return frames evicted from history.
if let Some(ref mut pipeline) = self.pipelines.get_mut(&frame_change.new_pipeline_id) { if let Some(ref mut pipeline) = self.pipelines.get_mut(&frame_change.new_pipeline_id) {
@ -1958,8 +1948,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
self.clear_joint_session_future(top_level_frame_id); self.clear_joint_session_future(top_level_frame_id);
} }
// Build frame tree and send permission // Build frame tree
self.send_frame_tree_and_grant_paint_permission(); self.send_frame_tree();
} }
fn handle_activate_document_msg(&mut self, pipeline_id: PipelineId) { fn handle_activate_document_msg(&mut self, pipeline_id: PipelineId) {
@ -2339,20 +2329,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}) })
} }
// Revoke paint permission from a pipeline, and all children. // Send the current frame tree to compositor
fn revoke_paint_permission(&self, pipeline_id: PipelineId) { fn send_frame_tree(&mut self) {
if let Some(pipeline) = self.pipelines.get(&pipeline_id) {
for frame in self.current_frame_tree_iter(pipeline.frame_id) {
if let Some(pipeline) = self.pipelines.get(&frame.current.pipeline_id) {
pipeline.revoke_paint_permission();
}
}
}
}
// Send the current frame tree to compositor, and grant paint
// permission to each pipeline in the current frame tree.
fn send_frame_tree_and_grant_paint_permission(&mut self) {
// Note that this function can panic, due to ipc-channel creation failure. // Note that this function can panic, due to ipc-channel creation failure.
// avoiding this panic would require a mechanism for dealing // avoiding this panic would require a mechanism for dealing
// with low-resource scenarios. // with low-resource scenarios.
@ -2365,10 +2343,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
return; // Our message has been discarded, probably shutting down. return; // Our message has been discarded, probably shutting down.
} }
} }
for frame in self.current_frame_tree_iter(self.root_frame_id) {
self.pipelines.get(&frame.current.pipeline_id).map(|pipeline| pipeline.grant_paint_permission());
}
} }
/// For a given pipeline, determine the mozbrowser iframe that transitively contains /// For a given pipeline, determine the mozbrowser iframe that transitively contains

View file

@ -22,7 +22,6 @@ extern crate gaol;
extern crate gfx; extern crate gfx;
extern crate gfx_traits; extern crate gfx_traits;
extern crate ipc_channel; extern crate ipc_channel;
extern crate layers;
extern crate layout_traits; extern crate layout_traits;
#[macro_use] #[macro_use]
extern crate log; extern crate log;

View file

@ -11,11 +11,9 @@ use euclid::size::TypedSize2D;
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
use gaol; use gaol;
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use gfx::paint_thread::{LayoutToPaintMsg, PaintThread}; use gfx_traits::DevicePixel;
use gfx_traits::ChromeToPaintMsg;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER; use ipc_channel::router::ROUTER;
use layers::geometry::DevicePixel;
use layout_traits::LayoutThreadFactory; use layout_traits::LayoutThreadFactory;
use msg::constellation_msg::{FrameId, FrameType, LoadData, PipelineId, PipelineNamespaceId}; use msg::constellation_msg::{FrameId, FrameType, LoadData, PipelineId, PipelineNamespaceId};
use net_traits::{IpcSend, ResourceThreads}; use net_traits::{IpcSend, ResourceThreads};
@ -31,11 +29,9 @@ use std::env;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::io::Error as IOError; use std::io::Error as IOError;
use std::process; use std::process;
use std::sync::mpsc::{Sender, channel}; use std::sync::mpsc::Sender;
use style_traits::{PagePx, ViewportPx}; use style_traits::{PagePx, ViewportPx};
use url::Url; use url::Url;
use util;
use util::ipc::OptionalIpcSender;
use util::opts::{self, Opts}; use util::opts::{self, Opts};
use util::prefs::{PREFS, Pref}; use util::prefs::{PREFS, Pref};
use webrender_traits; use webrender_traits;
@ -58,7 +54,6 @@ pub struct Pipeline {
pub layout_chan: IpcSender<LayoutControlMsg>, pub layout_chan: IpcSender<LayoutControlMsg>,
/// A channel to the compositor. /// A channel to the compositor.
pub compositor_proxy: Box<CompositorProxy + 'static + Send>, pub compositor_proxy: Box<CompositorProxy + 'static + Send>,
pub chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
/// URL corresponding to the most recently-loaded page. /// URL corresponding to the most recently-loaded page.
pub url: Url, pub url: Url,
/// The title of the most recently-loaded page. /// The title of the most recently-loaded page.
@ -127,8 +122,8 @@ pub struct InitialPipelineState {
pub pipeline_namespace_id: PipelineNamespaceId, pub pipeline_namespace_id: PipelineNamespaceId,
/// Pipeline visibility to be inherited /// Pipeline visibility to be inherited
pub prev_visibility: Option<bool>, pub prev_visibility: Option<bool>,
/// Optional webrender api (if enabled). /// Webrender api.
pub webrender_api_sender: Option<webrender_traits::RenderApiSender>, pub webrender_api_sender: webrender_traits::RenderApiSender,
/// Whether this pipeline is considered private. /// Whether this pipeline is considered private.
pub is_private: bool, pub is_private: bool,
} }
@ -143,8 +138,6 @@ impl Pipeline {
{ {
// Note: we allow channel creation to panic, since recovering from this // Note: we allow channel creation to panic, since recovering from this
// probably requires a general low-memory strategy. // probably requires a general low-memory strategy.
let (layout_to_paint_chan, layout_to_paint_port) = util::ipc::optional_ipc_channel();
let (chrome_to_paint_chan, chrome_to_paint_port) = channel();
let (pipeline_chan, pipeline_port) = ipc::channel() let (pipeline_chan, pipeline_port) = ipc::channel()
.expect("Pipeline main chan");; .expect("Pipeline main chan");;
@ -160,7 +153,6 @@ impl Pipeline {
new_pipeline_id: state.id, new_pipeline_id: state.id,
frame_type: frame_type, frame_type: frame_type,
load_data: state.load_data.clone(), load_data: state.load_data.clone(),
paint_chan: layout_to_paint_chan.clone().to_opaque(),
pipeline_port: pipeline_port, pipeline_port: pipeline_port,
layout_to_constellation_chan: state.layout_to_constellation_chan.clone(), layout_to_constellation_chan: state.layout_to_constellation_chan.clone(),
content_process_shutdown_chan: layout_content_process_shutdown_chan.clone(), content_process_shutdown_chan: layout_content_process_shutdown_chan.clone(),
@ -178,16 +170,6 @@ impl Pipeline {
} }
}; };
PaintThread::create(state.id,
state.load_data.url.clone(),
chrome_to_paint_chan.clone(),
layout_to_paint_port,
chrome_to_paint_port,
state.compositor_proxy.clone_compositor_proxy(),
state.font_cache_thread.clone(),
state.time_profiler_chan.clone(),
state.mem_profiler_chan.clone());
let mut child_process = None; let mut child_process = None;
if let Some((script_port, pipeline_port)) = content_ports { if let Some((script_port, pipeline_port)) = content_ports {
// Route messages coming from content to devtools as appropriate. // Route messages coming from content to devtools as appropriate.
@ -238,7 +220,6 @@ impl Pipeline {
script_port: script_port, script_port: script_port,
opts: (*opts::get()).clone(), opts: (*opts::get()).clone(),
prefs: PREFS.cloned(), prefs: PREFS.cloned(),
layout_to_paint_chan: layout_to_paint_chan,
pipeline_port: pipeline_port, pipeline_port: pipeline_port,
pipeline_namespace_id: state.pipeline_namespace_id, pipeline_namespace_id: state.pipeline_namespace_id,
layout_content_process_shutdown_chan: layout_content_process_shutdown_chan, layout_content_process_shutdown_chan: layout_content_process_shutdown_chan,
@ -264,7 +245,6 @@ impl Pipeline {
script_chan, script_chan,
pipeline_chan, pipeline_chan,
state.compositor_proxy, state.compositor_proxy,
chrome_to_paint_chan,
state.is_private, state.is_private,
state.load_data.url, state.load_data.url,
state.window_size, state.window_size,
@ -281,7 +261,6 @@ impl Pipeline {
script_chan: IpcSender<ConstellationControlMsg>, script_chan: IpcSender<ConstellationControlMsg>,
layout_chan: IpcSender<LayoutControlMsg>, layout_chan: IpcSender<LayoutControlMsg>,
compositor_proxy: Box<CompositorProxy + 'static + Send>, compositor_proxy: Box<CompositorProxy + 'static + Send>,
chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
is_private: bool, is_private: bool,
url: Url, url: Url,
size: Option<TypedSize2D<f32, PagePx>>, size: Option<TypedSize2D<f32, PagePx>>,
@ -294,7 +273,6 @@ impl Pipeline {
script_chan: script_chan, script_chan: script_chan,
layout_chan: layout_chan, layout_chan: layout_chan,
compositor_proxy: compositor_proxy, compositor_proxy: compositor_proxy,
chrome_to_paint_chan: chrome_to_paint_chan,
url: url, url: url,
title: None, title: None,
children: vec!(), children: vec!(),
@ -306,15 +284,6 @@ impl Pipeline {
} }
} }
pub fn grant_paint_permission(&self) {
let _ = self.chrome_to_paint_chan.send(ChromeToPaintMsg::PaintPermissionGranted);
}
pub fn revoke_paint_permission(&self) {
debug!("pipeline revoking paint channel paint permission");
let _ = self.chrome_to_paint_chan.send(ChromeToPaintMsg::PaintPermissionRevoked);
}
pub fn exit(&self) { pub fn exit(&self) {
debug!("pipeline {:?} exiting", self.id); debug!("pipeline {:?} exiting", self.id);
@ -353,9 +322,6 @@ impl Pipeline {
if let Err(e) = self.script_chan.send(ConstellationControlMsg::ExitPipeline(self.id)) { if let Err(e) = self.script_chan.send(ConstellationControlMsg::ExitPipeline(self.id)) {
warn!("Sending script exit message failed ({}).", e); warn!("Sending script exit message failed ({}).", e);
} }
if let Err(e) = self.chrome_to_paint_chan.send(ChromeToPaintMsg::Exit) {
warn!("Sending paint exit message failed ({}).", e);
}
if let Err(e) = self.layout_chan.send(LayoutControlMsg::ExitNow) { if let Err(e) = self.layout_chan.send(LayoutControlMsg::ExitNow) {
warn!("Sending layout exit message failed ({}).", e); warn!("Sending layout exit message failed ({}).", e);
} }
@ -366,7 +332,6 @@ impl Pipeline {
id: self.id.clone(), id: self.id.clone(),
script_chan: self.script_chan.clone(), script_chan: self.script_chan.clone(),
layout_chan: self.layout_chan.clone(), layout_chan: self.layout_chan.clone(),
chrome_to_paint_chan: self.chrome_to_paint_chan.clone(),
} }
} }
@ -430,7 +395,6 @@ pub struct UnprivilegedPipelineContent {
script_chan: IpcSender<ConstellationControlMsg>, script_chan: IpcSender<ConstellationControlMsg>,
load_data: LoadData, load_data: LoadData,
script_port: IpcReceiver<ConstellationControlMsg>, script_port: IpcReceiver<ConstellationControlMsg>,
layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
opts: Opts, opts: Opts,
prefs: HashMap<String, Pref>, prefs: HashMap<String, Pref>,
pipeline_port: IpcReceiver<LayoutControlMsg>, pipeline_port: IpcReceiver<LayoutControlMsg>,
@ -439,7 +403,7 @@ pub struct UnprivilegedPipelineContent {
layout_content_process_shutdown_port: IpcReceiver<()>, layout_content_process_shutdown_port: IpcReceiver<()>,
script_content_process_shutdown_chan: IpcSender<()>, script_content_process_shutdown_chan: IpcSender<()>,
script_content_process_shutdown_port: IpcReceiver<()>, script_content_process_shutdown_port: IpcReceiver<()>,
webrender_api_sender: Option<webrender_traits::RenderApiSender>, webrender_api_sender: webrender_traits::RenderApiSender,
} }
impl UnprivilegedPipelineContent { impl UnprivilegedPipelineContent {
@ -472,7 +436,6 @@ impl UnprivilegedPipelineContent {
self.pipeline_port, self.pipeline_port,
self.layout_to_constellation_chan, self.layout_to_constellation_chan,
self.script_chan, self.script_chan,
self.layout_to_paint_chan,
self.image_cache_thread, self.image_cache_thread,
self.font_cache_thread, self.font_cache_thread,
self.time_profiler_chan, self.time_profiler_chan,

View file

@ -22,7 +22,6 @@ harfbuzz-sys = "0.1"
heapsize = "0.3.0" heapsize = "0.3.0"
heapsize_plugin = "0.1.2" heapsize_plugin = "0.1.2"
ipc-channel = "0.5" ipc-channel = "0.5"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
lazy_static = "0.2" lazy_static = "0.2"
libc = "0.2" libc = "0.2"
log = "0.3.5" log = "0.3.5"
@ -31,8 +30,6 @@ msg = {path = "../msg"}
net_traits = {path = "../net_traits"} net_traits = {path = "../net_traits"}
ordered-float = "0.2.2" ordered-float = "0.2.2"
plugins = {path = "../plugins"} plugins = {path = "../plugins"}
profile_traits = {path = "../profile_traits"}
rand = "0.3"
range = {path = "../range"} range = {path = "../range"}
rustc-serialize = "0.3" rustc-serialize = "0.3"
serde = "0.8" serde = "0.8"

View file

@ -112,7 +112,7 @@ pub struct Font {
shaper: Option<Shaper>, shaper: Option<Shaper>,
shape_cache: RefCell<HashMap<ShapeCacheEntry, Arc<GlyphStore>>>, shape_cache: RefCell<HashMap<ShapeCacheEntry, Arc<GlyphStore>>>,
glyph_advance_cache: RefCell<HashMap<u32, FractionalPixel>>, glyph_advance_cache: RefCell<HashMap<u32, FractionalPixel>>,
pub font_key: Option<webrender_traits::FontKey>, pub font_key: webrender_traits::FontKey,
} }
impl Font { impl Font {
@ -121,7 +121,7 @@ impl Font {
descriptor: FontTemplateDescriptor, descriptor: FontTemplateDescriptor,
requested_pt_size: Au, requested_pt_size: Au,
actual_pt_size: Au, actual_pt_size: Au,
font_key: Option<webrender_traits::FontKey>) -> Font { font_key: webrender_traits::FontKey) -> Font {
let metrics = handle.metrics(); let metrics = handle.metrics();
Font { Font {
handle: handle, handle: handle,

View file

@ -349,16 +349,18 @@ impl FontCache {
} }
fn get_font_template_info(&mut self, template: Arc<FontTemplateData>) -> FontTemplateInfo { fn get_font_template_info(&mut self, template: Arc<FontTemplateData>) -> FontTemplateInfo {
let webrender_fonts = &mut self.webrender_fonts; let mut font_key = None;
let font_key = self.webrender_api.as_ref().map(|webrender_api| {
*webrender_fonts.entry(template.identifier.clone()).or_insert_with(|| { 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()) { match (template.bytes_if_in_memory(), template.native_font()) {
(Some(bytes), _) => webrender_api.add_raw_font(bytes), (Some(bytes), _) => webrender_api.add_raw_font(bytes),
(None, Some(native_font)) => webrender_api.add_native_font(native_font), (None, Some(native_font)) => webrender_api.add_native_font(native_font),
(None, None) => webrender_api.add_raw_font(template.bytes().clone()), (None, None) => webrender_api.add_raw_font(template.bytes().clone()),
} }
}) }));
}); }
FontTemplateInfo { FontTemplateInfo {
font_template: template, font_template: template,

View file

@ -109,7 +109,7 @@ impl FontContext {
descriptor: FontTemplateDescriptor, descriptor: FontTemplateDescriptor,
pt_size: Au, pt_size: Au,
variant: font_variant::T, 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 // TODO: (Bug #3463): Currently we only support fake small-caps
// painting. We should also support true small-caps (where the // painting. We should also support true small-caps (where the
// font supports it) in the future. // font supports it) in the future.
@ -197,7 +197,8 @@ impl FontContext {
desc.clone(), desc.clone(),
style.font_size, style.font_size,
style.font_variant, style.font_variant,
template_info.font_key); template_info.font_key
.expect("No font key present!"));
let font = match layout_font { let font = match layout_font {
Ok(layout_font) => { Ok(layout_font) => {
let layout_font = Rc::new(RefCell::new(layout_font)); let layout_font = Rc::new(RefCell::new(layout_font));
@ -242,7 +243,7 @@ impl FontContext {
desc.clone(), desc.clone(),
style.font_size, style.font_size,
style.font_variant, style.font_variant,
template_info.font_key); template_info.font_key.expect("No font key present!"));
match layout_font { match layout_font {
Ok(layout_font) => { Ok(layout_font) => {
let layout_font = Rc::new(RefCell::new(layout_font)); let layout_font = Rc::new(RefCell::new(layout_font));

View file

@ -9,7 +9,6 @@
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(custom_attribute)] #![feature(custom_attribute)]
#![feature(custom_derive)] #![feature(custom_derive)]
#![feature(mpsc_select)]
#![feature(plugin)] #![feature(plugin)]
#![feature(proc_macro)] #![feature(proc_macro)]
#![feature(range_contains)] #![feature(range_contains)]
@ -57,7 +56,6 @@ extern crate harfbuzz_sys as harfbuzz;
extern crate heapsize; extern crate heapsize;
extern crate ipc_channel; extern crate ipc_channel;
extern crate layers;
#[allow(unused_extern_crates)] #[allow(unused_extern_crates)]
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
@ -69,9 +67,6 @@ extern crate msg;
extern crate net_traits; extern crate net_traits;
extern crate ordered_float; extern crate ordered_float;
#[macro_use] #[macro_use]
extern crate profile_traits;
extern crate rand;
#[macro_use]
extern crate range; extern crate range;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate serde; extern crate serde;
@ -110,8 +105,6 @@ pub mod font_cache_thread;
pub mod font_context; pub mod font_context;
pub mod font_template; pub mod font_template;
pub mod paint_thread;
// Platform-specific implementations. // Platform-specific implementations.
#[allow(unsafe_code)] #[allow(unsafe_code)]
mod platform; mod platform;

View file

@ -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 },
];

View file

@ -29,7 +29,7 @@ pub struct TextRun {
pub font_template: Arc<FontTemplateData>, pub font_template: Arc<FontTemplateData>,
pub actual_pt_size: Au, pub actual_pt_size: Au,
pub font_metrics: FontMetrics, 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. /// The glyph runs that make up this text run.
pub glyphs: Arc<Vec<GlyphRun>>, pub glyphs: Arc<Vec<GlyphRun>>,
pub bidi_level: u8, pub bidi_level: u8,

View file

@ -11,13 +11,9 @@ path = "lib.rs"
[dependencies] [dependencies]
azure = {git = "https://github.com/servo/rust-azure", features = ["plugins"]} azure = {git = "https://github.com/servo/rust-azure", features = ["plugins"]}
euclid = "0.10.1"
heapsize = "0.3.0" heapsize = "0.3.0"
heapsize_plugin = "0.1.2" heapsize_plugin = "0.1.2"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
msg = {path = "../msg"}
plugins = {path = "../plugins"} plugins = {path = "../plugins"}
profile_traits = {path = "../profile_traits"}
range = {path = "../range"} range = {path = "../range"}
rustc-serialize = "0.3" rustc-serialize = "0.3"
serde = "0.8" serde = "0.8"

View file

@ -11,11 +11,7 @@
#![deny(unsafe_code)] #![deny(unsafe_code)]
extern crate azure; extern crate azure;
extern crate euclid;
extern crate heapsize; extern crate heapsize;
extern crate layers;
extern crate msg;
extern crate profile_traits;
#[macro_use] #[macro_use]
extern crate range; extern crate range;
extern crate rustc_serialize; extern crate rustc_serialize;
@ -24,16 +20,8 @@ extern crate serde;
extern crate serde_derive; extern crate serde_derive;
pub mod color; pub mod color;
mod paint_listener;
pub mod print_tree; pub mod print_tree;
pub use paint_listener::PaintListener;
use azure::azure_hl::Color;
use euclid::Matrix4D;
use euclid::rect::Rect;
use layers::layers::BufferRequest;
use msg::constellation_msg::PipelineId;
use profile_traits::mem::ReportsChan;
use range::RangeIndex; use range::RangeIndex;
use std::fmt::{self, Debug, Formatter}; use std::fmt::{self, Debug, Formatter};
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
@ -50,6 +38,20 @@ static NEXT_SPECIAL_STACKING_CONTEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;
/// Note that we assume that the top 16 bits of the address space are unused on the platform. /// Note that we assume that the top 16 bits of the address space are unused on the platform.
const SPECIAL_STACKING_CONTEXT_ID_MASK: usize = 0xffff; const SPECIAL_STACKING_CONTEXT_ID_MASK: usize = 0xffff;
// Units for use with euclid::length and euclid::scale_factor.
/// One hardware pixel.
///
/// This unit corresponds to the smallest addressable element of the display hardware.
#[derive(Copy, Clone, RustcEncodable, Debug)]
pub enum DevicePixel {}
/// One pixel in layer coordinate space.
///
/// This unit corresponds to a "pixel" in layer coordinate space, which after scaling and
/// transformation becomes a device pixel.
#[derive(Copy, Clone, RustcEncodable, Debug)]
pub enum LayerPixel {}
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum LayerKind { pub enum LayerKind {
@ -128,33 +130,6 @@ impl LayerId {
} }
} }
/// All layer-specific information that the painting task sends to the compositor other than the
/// buffer contents of the layer itself.
#[derive(Copy, Clone, HeapSizeOf)]
pub struct LayerProperties {
/// An opaque ID. This is usually the address of the flow and index of the box within it.
pub id: LayerId,
/// The id of the parent layer.
pub parent_id: Option<LayerId>,
/// The position and size of the layer in pixels.
pub rect: Rect<f32>,
/// The background color of the layer.
pub background_color: Color,
/// The scrolling policy of this layer.
pub scroll_policy: ScrollPolicy,
/// The transform for this layer
pub transform: Matrix4D<f32>,
/// The perspective transform for this layer
pub perspective: Matrix4D<f32>,
/// The subpage that this layer represents. If this is `Some`, this layer represents an
/// iframe.
pub subpage_pipeline_id: Option<PipelineId>,
/// Whether this layer establishes a new 3d rendering context.
pub establishes_3d_context: bool,
/// Whether this layer scrolls its overflow area.
pub scrolls_overflow_area: bool,
}
/// A newtype struct for denoting the age of messages; prevents race conditions. /// A newtype struct for denoting the age of messages; prevents race conditions.
#[derive(PartialEq, Eq, Debug, Copy, Clone, PartialOrd, Ord, Deserialize, Serialize)] #[derive(PartialEq, Eq, Debug, Copy, Clone, PartialOrd, Ord, Deserialize, Serialize)]
pub struct Epoch(pub u32); pub struct Epoch(pub u32);
@ -272,19 +247,3 @@ int_range_index! {
#[derive(HeapSizeOf)] #[derive(HeapSizeOf)]
struct ByteIndex(isize) struct ByteIndex(isize)
} }
pub struct PaintRequest {
pub buffer_requests: Vec<BufferRequest>,
pub scale: f32,
pub layer_id: LayerId,
pub epoch: Epoch,
pub layer_kind: LayerKind,
}
pub enum ChromeToPaintMsg {
Paint(Vec<PaintRequest>, FrameTreeId),
PaintPermissionGranted,
PaintPermissionRevoked,
CollectReports(ReportsChan),
Exit,
}

View file

@ -1,37 +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/. */
use Epoch;
use FrameTreeId;
use LayerId;
use LayerProperties;
use layers::layers::{BufferRequest, LayerBufferSet};
use layers::platform::surface::NativeDisplay;
use msg::constellation_msg::PipelineId;
/// The interface used by the painter to acquire draw targets for each paint frame and
/// submit them to be drawn to the display.
pub trait PaintListener {
fn native_display(&mut self) -> Option<NativeDisplay>;
/// Informs the compositor of the layers for the given pipeline. The compositor responds by
/// creating and/or destroying paint layers as necessary.
fn initialize_layers_for_pipeline(&mut self,
pipeline_id: PipelineId,
properties: Vec<LayerProperties>,
epoch: Epoch);
/// Sends new buffers for the given layers to the compositor.
fn assign_painted_buffers(&mut self,
pipeline_id: PipelineId,
epoch: Epoch,
replies: Vec<(LayerId, Box<LayerBufferSet>)>,
frame_tree_id: FrameTreeId);
/// Inform the compositor that these buffer requests will be ignored.
fn ignore_buffer_requests(&mut self, buffer_requests: Vec<BufferRequest>);
// Notification that the paint task wants to exit.
fn notify_paint_thread_exiting(&mut self, pipeline_id: PipelineId);
}

View file

@ -31,7 +31,7 @@ use app_units::{Au, MAX_AU};
use context::{LayoutContext, SharedLayoutContext}; use context::{LayoutContext, SharedLayoutContext};
use display_list_builder::{BorderPaintingMode, DisplayListBuildState, FragmentDisplayListBuilding}; use display_list_builder::{BorderPaintingMode, DisplayListBuildState, FragmentDisplayListBuilding};
use display_list_builder::BlockFlowDisplayListBuilding; use display_list_builder::BlockFlowDisplayListBuilding;
use euclid::{Point2D, Rect, Size2D}; use euclid::{Point2D, Size2D};
use floats::{ClearType, FloatKind, Floats, PlacementInfo}; use floats::{ClearType, FloatKind, Floats, PlacementInfo};
use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag}; use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag};
use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT}; use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT};
@ -64,10 +64,6 @@ use style::properties::ServoComputedValues;
use style::values::computed::{LengthOrNone, LengthOrPercentageOrNone}; use style::values::computed::{LengthOrNone, LengthOrPercentageOrNone};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use util::clamp; use util::clamp;
use util::geometry::max_rect;
/// The number of screens of data we're allowed to generate display lists for in each direction.
const DISPLAY_PORT_SIZE_FACTOR: i32 = 8;
/// Information specific to floated blocks. /// Information specific to floated blocks.
#[derive(Clone, RustcEncodable)] #[derive(Clone, RustcEncodable)]
@ -1959,7 +1955,7 @@ impl Flow for BlockFlow {
} }
} }
fn compute_absolute_position(&mut self, layout_context: &SharedLayoutContext) { fn compute_absolute_position(&mut self, _layout_context: &SharedLayoutContext) {
if self.base.flags.contains(NEEDS_LAYER) { if self.base.flags.contains(NEEDS_LAYER) {
self.fragment.flags.insert(HAS_LAYER) self.fragment.flags.insert(HAS_LAYER)
} }
@ -1970,7 +1966,6 @@ impl Flow for BlockFlow {
if self.is_root() { if self.is_root() {
self.base.clip = ClippingRegion::max(); self.base.clip = ClippingRegion::max();
self.base.stacking_relative_position_of_display_port = max_rect();
} }
let transform_style = self.fragment.style().get_used_transform_style(); let transform_style = self.fragment.style().get_used_transform_style();
@ -1983,7 +1978,6 @@ impl Flow for BlockFlow {
(overflow_x::T::auto, _) | (overflow_x::T::scroll, _) | (overflow_x::T::auto, _) | (overflow_x::T::scroll, _) |
(_, overflow_x::T::auto) | (_, overflow_x::T::scroll) => { (_, overflow_x::T::auto) | (_, overflow_x::T::scroll) => {
self.base.clip = ClippingRegion::max(); self.base.clip = ClippingRegion::max();
self.base.stacking_relative_position_of_display_port = max_rect();
} }
_ => {} _ => {}
} }
@ -2085,25 +2079,6 @@ impl Flow for BlockFlow {
self.base.stacking_relative_position + relative_offset self.base.stacking_relative_position + relative_offset
}; };
let stacking_relative_position_of_display_port_for_children =
if is_stacking_context || self.is_root() {
let visible_rect =
match layout_context.visible_rects.get(&self.layer_id()) {
Some(visible_rect) => *visible_rect,
None => Rect::new(Point2D::zero(), layout_context.style_context.viewport_size),
};
let viewport_size = layout_context.style_context.viewport_size;
visible_rect.inflate(viewport_size.width * DISPLAY_PORT_SIZE_FACTOR,
viewport_size.height * DISPLAY_PORT_SIZE_FACTOR)
} else if is_stacking_context {
self.base
.stacking_relative_position_of_display_port
.translate(&-self.base.stacking_relative_position)
} else {
self.base.stacking_relative_position_of_display_port
};
let stacking_relative_border_box = let stacking_relative_border_box =
self.fragment self.fragment
.stacking_relative_border_box(&self.base.stacking_relative_position, .stacking_relative_border_box(&self.base.stacking_relative_position,
@ -2168,8 +2143,6 @@ impl Flow for BlockFlow {
flow::mut_base(kid).late_absolute_position_info = flow::mut_base(kid).late_absolute_position_info =
late_absolute_position_info_for_children; late_absolute_position_info_for_children;
flow::mut_base(kid).stacking_relative_position_of_display_port =
stacking_relative_position_of_display_port_for_children;
// This clipping region is in our coordinate system. The child will fix it up to be in // This clipping region is in our coordinate system. The child will fix it up to be in
// its own coordinate system by itself if necessary. // its own coordinate system by itself if necessary.

View file

@ -15,7 +15,7 @@ use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context::FontContext; use gfx::font_context::FontContext;
use gfx_traits::LayerId; use gfx_traits::LayerId;
use heapsize::HeapSizeOf; use heapsize::HeapSizeOf;
use ipc_channel::ipc::{self, IpcSharedMemory}; use ipc_channel::ipc;
use net_traits::image::base::Image; use net_traits::image::base::Image;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread, ImageResponse, ImageState}; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread, ImageResponse, ImageState};
use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder}; use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder};
@ -196,36 +196,27 @@ impl SharedLayoutContext {
pub fn get_webrender_image_for_url(&self, pub fn get_webrender_image_for_url(&self,
url: &Url, url: &Url,
use_placeholder: UsePlaceholder, use_placeholder: UsePlaceholder)
fetch_image_data_as_well: bool) -> Option<WebRenderImageInfo> {
-> Option<(WebRenderImageInfo, Option<IpcSharedMemory>)> { if let Some(existing_webrender_image) = self.webrender_image_cache
if !fetch_image_data_as_well { .read()
let webrender_image_cache = self.webrender_image_cache.read().unwrap(); .unwrap()
if let Some(existing_webrender_image) = .get(&((*url).clone(), use_placeholder)) {
webrender_image_cache.get(&((*url).clone(), use_placeholder)) { return Some((*existing_webrender_image).clone())
return Some(((*existing_webrender_image).clone(), None))
}
} }
match self.get_or_request_image_or_meta((*url).clone(), use_placeholder) { match self.get_or_request_image_or_meta((*url).clone(), use_placeholder) {
Some(ImageOrMetadataAvailable::ImageAvailable(image)) => { Some(ImageOrMetadataAvailable::ImageAvailable(image)) => {
let image_info = WebRenderImageInfo::from_image(&*image); let image_info = WebRenderImageInfo::from_image(&*image);
if image_info.key.is_none() { if image_info.key.is_none() {
let bytes = if !fetch_image_data_as_well { Some(image_info)
None } else {
} else {
Some(image.bytes.clone())
};
Some((image_info, bytes))
} else if !fetch_image_data_as_well {
let mut webrender_image_cache = self.webrender_image_cache let mut webrender_image_cache = self.webrender_image_cache
.write() .write()
.unwrap(); .unwrap();
webrender_image_cache.insert(((*url).clone(), use_placeholder), webrender_image_cache.insert(((*url).clone(), use_placeholder),
image_info); image_info);
Some((image_info, None)) Some(image_info)
} else {
Some((image_info, Some(image.bytes.clone())))
} }
} }
None | Some(ImageOrMetadataAvailable::MetadataAvailable(_)) => None, None | Some(ImageOrMetadataAvailable::MetadataAvailable(_)) => None,

View file

@ -25,10 +25,9 @@ use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayIte
use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion}; use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion};
use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayListSection, GradientDisplayItem}; use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayListSection, GradientDisplayItem};
use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGLDisplayItem}; use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGLDisplayItem};
use gfx::display_list::{LayerInfo, LayeredItem, LineDisplayItem, OpaqueNode}; use gfx::display_list::{LayerInfo, LineDisplayItem, OpaqueNode};
use gfx::display_list::{SolidColorDisplayItem, StackingContext, StackingContextType}; use gfx::display_list::{SolidColorDisplayItem, StackingContext, StackingContextType};
use gfx::display_list::{TextDisplayItem, TextOrientation, WebRenderImageInfo}; use gfx::display_list::{TextDisplayItem, TextOrientation, WebRenderImageInfo};
use gfx::paint_thread::THREAD_TINT_COLORS;
use gfx_traits::{ScrollPolicy, StackingContextId, color}; use gfx_traits::{ScrollPolicy, StackingContextId, color};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT}; use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc; use ipc_channel::ipc;
@ -60,6 +59,17 @@ use table_cell::CollapsedBordersForCell;
use url::Url; use url::Url;
use util::opts; use util::opts;
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 },
];
fn get_cyclic<T>(arr: &[T], index: usize) -> &T { fn get_cyclic<T>(arr: &[T], index: usize) -> &T {
&arr[index % arr.len()] &arr[index % arr.len()]
} }
@ -230,8 +240,6 @@ pub trait FragmentDisplayListBuilding {
/// * `relative_containing_block_size`: The size of the containing block that /// * `relative_containing_block_size`: The size of the containing block that
/// `position: relative` makes use of. /// `position: relative` makes use of.
/// * `clip`: The region to clip the display items to. /// * `clip`: The region to clip the display items to.
/// * `stacking_relative_display_port`: The position and size of the display port with respect
/// to the nearest ancestor stacking context.
fn build_display_list(&mut self, fn build_display_list(&mut self,
state: &mut DisplayListBuildState, state: &mut DisplayListBuildState,
stacking_relative_flow_origin: &Point2D<Au>, stacking_relative_flow_origin: &Point2D<Au>,
@ -239,8 +247,7 @@ pub trait FragmentDisplayListBuilding {
relative_containing_block_mode: WritingMode, relative_containing_block_mode: WritingMode,
border_painting_mode: BorderPaintingMode, border_painting_mode: BorderPaintingMode,
display_list_section: DisplayListSection, display_list_section: DisplayListSection,
clip: &ClippingRegion, clip: &ClippingRegion);
stacking_relative_display_port: &Rect<Au>);
/// Adjusts the clipping region for all descendants of this fragment as appropriate. /// Adjusts the clipping region for all descendants of this fragment as appropriate.
fn adjust_clipping_region_for_children(&self, fn adjust_clipping_region_for_children(&self,
@ -497,13 +504,11 @@ impl FragmentDisplayListBuilding for Fragment {
image_url: &Url, image_url: &Url,
index: usize) { index: usize) {
let background = style.get_background(); let background = style.get_background();
let fetch_image_data_as_well = !opts::get().use_webrender;
let webrender_image = state.shared_layout_context let webrender_image = state.shared_layout_context
.get_webrender_image_for_url(image_url, .get_webrender_image_for_url(image_url,
UsePlaceholder::No, UsePlaceholder::No);
fetch_image_data_as_well);
if let Some((webrender_image, image_data)) = webrender_image { if let Some(webrender_image) = webrender_image {
debug!("(building display list) building background image"); debug!("(building display list) building background image");
// Use `background-size` to get the size. // Use `background-size` to get the size.
@ -633,7 +638,7 @@ impl FragmentDisplayListBuilding for Fragment {
state.add_display_item(DisplayItem::ImageClass(box ImageDisplayItem { state.add_display_item(DisplayItem::ImageClass(box ImageDisplayItem {
base: base, base: base,
webrender_image: webrender_image, webrender_image: webrender_image,
image_data: image_data.map(Arc::new), image_data: None,
stretch_size: stretch_size, stretch_size: stretch_size,
tile_spacing: tile_spacing, tile_spacing: tile_spacing,
image_rendering: style.get_inheritedbox().image_rendering.clone(), image_rendering: style.get_inheritedbox().image_rendering.clone(),
@ -1080,8 +1085,7 @@ impl FragmentDisplayListBuilding for Fragment {
relative_containing_block_mode: WritingMode, relative_containing_block_mode: WritingMode,
border_painting_mode: BorderPaintingMode, border_painting_mode: BorderPaintingMode,
display_list_section: DisplayListSection, display_list_section: DisplayListSection,
clip: &ClippingRegion, clip: &ClippingRegion) {
stacking_relative_display_port: &Rect<Au>) {
self.restyle_damage.remove(REPAINT); self.restyle_damage.remove(REPAINT);
if self.style().get_inheritedbox().visibility != visibility::T::visible { if self.style().get_inheritedbox().visibility != visibility::T::visible {
return return
@ -1102,14 +1106,6 @@ impl FragmentDisplayListBuilding for Fragment {
stacking_relative_flow_origin, stacking_relative_flow_origin,
self); self);
// webrender deals with all culling via aabb
if !opts::get().use_webrender {
if !stacking_relative_border_box.intersects(stacking_relative_display_port) {
debug!("Fragment::build_display_list: outside display port");
return
}
}
// Check the clip rect. If there's nothing to render at all, don't even construct display // Check the clip rect. If there's nothing to render at all, don't even construct display
// list items. // list items.
let empty_rect = !clip.might_intersect_rect(&stacking_relative_border_box); let empty_rect = !clip.might_intersect_rect(&stacking_relative_border_box);
@ -1270,17 +1266,7 @@ impl FragmentDisplayListBuilding for Fragment {
iframe: fragment_info.pipeline_id, iframe: fragment_info.pipeline_id,
}); });
if opts::get().use_webrender { state.add_display_item(item);
state.add_display_item(item);
} else {
state.add_display_item(DisplayItem::LayeredItemClass(box LayeredItem {
item: item,
layer_info: LayerInfo::new(self.layer_id(),
ScrollPolicy::Scrollable,
Some(fragment_info.pipeline_id),
color::transparent()),
}));
}
} }
} }
SpecificFragmentInfo::Image(ref mut image_fragment) => { SpecificFragmentInfo::Image(ref mut image_fragment) => {
@ -1311,7 +1297,6 @@ impl FragmentDisplayListBuilding for Fragment {
let computed_width = canvas_fragment_info.canvas_inline_size().to_px(); let computed_width = canvas_fragment_info.canvas_inline_size().to_px();
let computed_height = canvas_fragment_info.canvas_block_size().to_px(); let computed_height = canvas_fragment_info.canvas_block_size().to_px();
let layer_id = self.layer_id();
let canvas_data = match canvas_fragment_info.ipc_renderer { let canvas_data = match canvas_fragment_info.ipc_renderer {
Some(ref ipc_renderer) => { Some(ref ipc_renderer) => {
let ipc_renderer = ipc_renderer.lock().unwrap(); let ipc_renderer = ipc_renderer.lock().unwrap();
@ -1338,7 +1323,7 @@ impl FragmentDisplayListBuilding for Fragment {
width: computed_width as u32, width: computed_width as u32,
height: computed_height as u32, height: computed_height as u32,
format: PixelFormat::RGBA8, format: PixelFormat::RGBA8,
key: canvas_data.image_key, key: Some(canvas_data.image_key),
}, },
stretch_size: stacking_relative_content_box.size, stretch_size: stacking_relative_content_box.size,
tile_spacing: Size2D::zero(), tile_spacing: Size2D::zero(),
@ -1353,17 +1338,7 @@ impl FragmentDisplayListBuilding for Fragment {
} }
}; };
if opts::get().use_webrender { state.add_display_item(display_item);
state.add_display_item(display_item);
} else {
state.add_display_item(DisplayItem::LayeredItemClass(box LayeredItem {
item: display_item,
layer_info: LayerInfo::new(layer_id,
ScrollPolicy::Scrollable,
None,
color::transparent()),
}));
}
} }
} }
SpecificFragmentInfo::UnscannedText(_) => { SpecificFragmentInfo::UnscannedText(_) => {
@ -1381,7 +1356,6 @@ impl FragmentDisplayListBuilding for Fragment {
scroll_policy: ScrollPolicy, scroll_policy: ScrollPolicy,
mode: StackingContextCreationMode) mode: StackingContextCreationMode)
-> StackingContext { -> StackingContext {
let use_webrender = opts::get().use_webrender;
let border_box = match mode { let border_box = match mode {
StackingContextCreationMode::InnerScrollWrapper => { StackingContextCreationMode::InnerScrollWrapper => {
Rect::new(Point2D::zero(), base_flow.overflow.scroll.size) Rect::new(Point2D::zero(), base_flow.overflow.scroll.size)
@ -1396,10 +1370,7 @@ impl FragmentDisplayListBuilding for Fragment {
} }
}; };
let overflow = match mode { let overflow = match mode {
StackingContextCreationMode::InnerScrollWrapper if !use_webrender => { StackingContextCreationMode::InnerScrollWrapper => {
Rect::new(Point2D::zero(), base_flow.overflow.paint.size)
}
StackingContextCreationMode::InnerScrollWrapper if use_webrender => {
Rect::new(Point2D::zero(), base_flow.overflow.scroll.size) Rect::new(Point2D::zero(), base_flow.overflow.scroll.size)
} }
StackingContextCreationMode::OuterScrollWrapper => { StackingContextCreationMode::OuterScrollWrapper => {
@ -1874,8 +1845,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
.relative_containing_block_mode, .relative_containing_block_mode,
border_painting_mode, border_painting_mode,
background_border_section, background_border_section,
&self.base.clip, &self.base.clip);
&self.base.stacking_relative_position_of_display_port);
self.base.build_display_items_for_debugging_tint(state, self.fragment.node); self.base.build_display_items_for_debugging_tint(state, self.fragment.node);
} }
@ -1982,8 +1952,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
.relative_containing_block_mode, .relative_containing_block_mode,
BorderPaintingMode::Separate, BorderPaintingMode::Separate,
DisplayListSection::Content, DisplayListSection::Content,
&self.base.clip, &self.base.clip);
&self.base.stacking_relative_position_of_display_port);
} }
fn build_display_list_for_inline(&mut self, state: &mut DisplayListBuildState) { fn build_display_list_for_inline(&mut self, state: &mut DisplayListBuildState) {
@ -2039,10 +2008,7 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
.relative_containing_block_mode, .relative_containing_block_mode,
BorderPaintingMode::Separate, BorderPaintingMode::Separate,
DisplayListSection::Content, DisplayListSection::Content,
&self.block_flow.base.clip, &self.block_flow.base.clip);
&self.block_flow
.base
.stacking_relative_position_of_display_port);
} }
// Draw the rest of the block. // Draw the rest of the block.

View file

@ -29,7 +29,7 @@ use app_units::Au;
use block::{BlockFlow, FormattingContextType}; use block::{BlockFlow, FormattingContextType};
use context::{LayoutContext, SharedLayoutContext}; use context::{LayoutContext, SharedLayoutContext};
use display_list_builder::DisplayListBuildState; use display_list_builder::DisplayListBuildState;
use euclid::{Point2D, Rect, Size2D}; use euclid::{Point2D, Size2D};
use floats::{Floats, SpeculatedFloatPlacement}; use floats::{Floats, SpeculatedFloatPlacement};
use flow_list::{FlowList, MutFlowListIterator}; use flow_list::{FlowList, MutFlowListIterator};
use flow_ref::{self, FlowRef, WeakFlowRef}; use flow_ref::{self, FlowRef, WeakFlowRef};
@ -940,12 +940,6 @@ pub struct BaseFlow {
/// this is in the flow's own coordinate system. /// this is in the flow's own coordinate system.
pub clip: ClippingRegion, pub clip: ClippingRegion,
/// The stacking-relative position of the display port.
///
/// FIXME(pcwalton): This might be faster as an Arc, since this varies only
/// per-stacking-context.
pub stacking_relative_position_of_display_port: Rect<Au>,
/// The writing mode for this flow. /// The writing mode for this flow.
pub writing_mode: WritingMode, pub writing_mode: WritingMode,
@ -1124,7 +1118,6 @@ impl BaseFlow {
early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode), early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode),
late_absolute_position_info: LateAbsolutePositionInfo::new(), late_absolute_position_info: LateAbsolutePositionInfo::new(),
clip: ClippingRegion::max(), clip: ClippingRegion::max(),
stacking_relative_position_of_display_port: Rect::zero(),
flags: flags, flags: flags,
writing_mode: writing_mode, writing_mode: writing_mode,
thread_id: 0, thread_id: 0,

View file

@ -1566,8 +1566,6 @@ impl Flow for InlineFlow {
block_flow.base.stacking_relative_position = block_flow.base.stacking_relative_position =
stacking_relative_content_box.origin; stacking_relative_content_box.origin;
block_flow.base.stacking_relative_position_of_display_port =
self.base.stacking_relative_position_of_display_port;
// Write the clip in our coordinate system into the child flow. (The kid will // Write the clip in our coordinate system into the child flow. (The kid will
// fix it up to be in its own coordinate system if necessary.) // fix it up to be in its own coordinate system if necessary.)
@ -1581,8 +1579,6 @@ impl Flow for InlineFlow {
block_flow.base.stacking_relative_position = block_flow.base.stacking_relative_position =
stacking_relative_border_box.origin; stacking_relative_border_box.origin;
block_flow.base.stacking_relative_position_of_display_port =
self.base.stacking_relative_position_of_display_port;
// As above, this is in our coordinate system for now. // As above, this is in our coordinate system for now.
block_flow.base.clip = self.base.clip.clone() block_flow.base.clip = self.base.clip.clone()
@ -1602,8 +1598,6 @@ impl Flow for InlineFlow {
block_flow.base.stacking_relative_position = block_flow.base.stacking_relative_position =
stacking_relative_border_box.origin; stacking_relative_border_box.origin;
block_flow.base.stacking_relative_position_of_display_port =
self.base.stacking_relative_position_of_display_port;
// As above, this is in our coordinate system for now. // As above, this is in our coordinate system for now.
block_flow.base.clip = self.base.clip.clone() block_flow.base.clip = self.base.clip.clone()

View file

@ -411,7 +411,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
builder.push_text(item.base.bounds.to_rectf(), builder.push_text(item.base.bounds.to_rectf(),
item.base.clip.to_clip_region(frame_builder), item.base.clip.to_clip_region(frame_builder),
glyphs, glyphs,
item.text_run.font_key.expect("Font not added to webrender!"), item.text_run.font_key,
item.text_color.to_colorf(), item.text_color.to_colorf(),
item.text_run.actual_pt_size, item.text_run.actual_pt_size,
item.blur_radius, item.blur_radius,

View file

@ -56,7 +56,6 @@ use gfx::display_list::{StackingContext, StackingContextType, WebRenderImageInfo
use gfx::font; use gfx::font;
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context; use gfx::font_context;
use gfx::paint_thread::LayoutToPaintMsg;
use gfx_traits::{Epoch, FragmentType, LayerId, ScrollPolicy, StackingContextId, color}; use gfx_traits::{Epoch, FragmentType, LayerId, ScrollPolicy, StackingContextId, color};
use heapsize::HeapSizeOf; use heapsize::HeapSizeOf;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
@ -120,7 +119,6 @@ use style::timer::Timer;
use style::workqueue::WorkQueue; use style::workqueue::WorkQueue;
use url::Url; use url::Url;
use util::geometry::max_rect; use util::geometry::max_rect;
use util::ipc::OptionalIpcSender;
use util::opts; use util::opts;
use util::prefs::PREFS; use util::prefs::PREFS;
use util::resource_files::read_resource_file; use util::resource_files::read_resource_file;
@ -164,9 +162,6 @@ pub struct LayoutThread {
/// The channel on which messages can be sent to the script thread. /// The channel on which messages can be sent to the script thread.
script_chan: IpcSender<ConstellationControlMsg>, script_chan: IpcSender<ConstellationControlMsg>,
/// The channel on which messages can be sent to the painting thread.
paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
/// The channel on which messages can be sent to the time profiler. /// The channel on which messages can be sent to the time profiler.
time_profiler_chan: time::ProfilerChan, time_profiler_chan: time::ProfilerChan,
@ -232,8 +227,8 @@ pub struct LayoutThread {
WebRenderImageInfo, WebRenderImageInfo,
BuildHasherDefault<FnvHasher>>>>, BuildHasherDefault<FnvHasher>>>>,
// Webrender interface, if enabled. // Webrender interface.
webrender_api: Option<webrender_traits::RenderApi>, webrender_api: webrender_traits::RenderApi,
/// The timer object to control the timing of the animations. This should /// The timer object to control the timing of the animations. This should
/// only be a test-mode timer during testing for animations. /// only be a test-mode timer during testing for animations.
@ -255,13 +250,12 @@ impl LayoutThreadFactory for LayoutThread {
pipeline_port: IpcReceiver<LayoutControlMsg>, pipeline_port: IpcReceiver<LayoutControlMsg>,
constellation_chan: IpcSender<ConstellationMsg>, constellation_chan: IpcSender<ConstellationMsg>,
script_chan: IpcSender<ConstellationControlMsg>, script_chan: IpcSender<ConstellationControlMsg>,
paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
image_cache_thread: ImageCacheThread, image_cache_thread: ImageCacheThread,
font_cache_thread: FontCacheThread, font_cache_thread: FontCacheThread,
time_profiler_chan: time::ProfilerChan, time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan, mem_profiler_chan: mem::ProfilerChan,
content_process_shutdown_chan: IpcSender<()>, content_process_shutdown_chan: IpcSender<()>,
webrender_api_sender: Option<webrender_traits::RenderApiSender>, webrender_api_sender: webrender_traits::RenderApiSender,
layout_threads: usize) { layout_threads: usize) {
thread::spawn_named(format!("LayoutThread {:?}", id), thread::spawn_named(format!("LayoutThread {:?}", id),
move || { move || {
@ -276,7 +270,6 @@ impl LayoutThreadFactory for LayoutThread {
pipeline_port, pipeline_port,
constellation_chan, constellation_chan,
script_chan, script_chan,
paint_chan,
image_cache_thread, image_cache_thread,
font_cache_thread, font_cache_thread,
time_profiler_chan, time_profiler_chan,
@ -388,12 +381,11 @@ impl LayoutThread {
pipeline_port: IpcReceiver<LayoutControlMsg>, pipeline_port: IpcReceiver<LayoutControlMsg>,
constellation_chan: IpcSender<ConstellationMsg>, constellation_chan: IpcSender<ConstellationMsg>,
script_chan: IpcSender<ConstellationControlMsg>, script_chan: IpcSender<ConstellationControlMsg>,
paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
image_cache_thread: ImageCacheThread, image_cache_thread: ImageCacheThread,
font_cache_thread: FontCacheThread, font_cache_thread: FontCacheThread,
time_profiler_chan: time::ProfilerChan, time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan, mem_profiler_chan: mem::ProfilerChan,
webrender_api_sender: Option<webrender_traits::RenderApiSender>, webrender_api_sender: webrender_traits::RenderApiSender,
layout_threads: usize) layout_threads: usize)
-> LayoutThread { -> LayoutThread {
let device = Device::new( let device = Device::new(
@ -439,7 +431,6 @@ impl LayoutThread {
pipeline_port: pipeline_receiver, pipeline_port: pipeline_receiver,
script_chan: script_chan.clone(), script_chan: script_chan.clone(),
constellation_chan: constellation_chan.clone(), constellation_chan: constellation_chan.clone(),
paint_chan: paint_chan,
time_profiler_chan: time_profiler_chan, time_profiler_chan: time_profiler_chan,
mem_profiler_chan: mem_profiler_chan, mem_profiler_chan: mem_profiler_chan,
image_cache_thread: image_cache_thread, image_cache_thread: image_cache_thread,
@ -460,7 +451,7 @@ impl LayoutThread {
expired_animations: Arc::new(RwLock::new(HashMap::new())), expired_animations: Arc::new(RwLock::new(HashMap::new())),
epoch: Epoch(0), epoch: Epoch(0),
viewport_size: Size2D::new(Au(0), Au(0)), viewport_size: Size2D::new(Au(0), Au(0)),
webrender_api: webrender_api_sender.map(|wr| wr.create_api()), webrender_api: webrender_api_sender.create_api(),
rw_data: Arc::new(Mutex::new( rw_data: Arc::new(Mutex::new(
LayoutThreadData { LayoutThreadData {
constellation_chan: constellation_chan, constellation_chan: constellation_chan,
@ -763,13 +754,12 @@ impl LayoutThread {
info.pipeline_port, info.pipeline_port,
info.constellation_chan, info.constellation_chan,
info.script_chan.clone(), info.script_chan.clone(),
info.paint_chan.to::<LayoutToPaintMsg>(),
self.image_cache_thread.clone(), self.image_cache_thread.clone(),
self.font_cache_thread.clone(), self.font_cache_thread.clone(),
self.time_profiler_chan.clone(), self.time_profiler_chan.clone(),
self.mem_profiler_chan.clone(), self.mem_profiler_chan.clone(),
info.content_process_shutdown_chan, info.content_process_shutdown_chan,
self.webrender_api.as_ref().map(|wr| wr.clone_sender()), self.webrender_api.clone_sender(),
info.layout_threads); info.layout_threads);
} }
@ -805,8 +795,6 @@ impl LayoutThread {
if let Some(ref mut traversal) = self.parallel_traversal { if let Some(ref mut traversal) = self.parallel_traversal {
traversal.shutdown() traversal.shutdown()
} }
let _ = self.paint_chan.send(LayoutToPaintMsg::Exit);
} }
fn handle_add_stylesheet<'a, 'b>(&self, fn handle_add_stylesheet<'a, 'b>(&self,
@ -1009,45 +997,38 @@ impl LayoutThread {
self.epoch.next(); self.epoch.next();
if let Some(ref mut webrender_api) = self.webrender_api { // TODO: Avoid the temporary conversion and build webrender sc/dl directly!
// TODO: Avoid the temporary conversion and build webrender sc/dl directly! let Epoch(epoch_number) = self.epoch;
let Epoch(epoch_number) = self.epoch; let epoch = webrender_traits::Epoch(epoch_number);
let epoch = webrender_traits::Epoch(epoch_number); let pipeline_id = self.id.to_webrender();
let pipeline_id = self.id.to_webrender();
// TODO(gw) For now only create a root scrolling layer! // TODO(gw) For now only create a root scrolling layer!
let mut frame_builder = WebRenderFrameBuilder::new(pipeline_id); let mut frame_builder = WebRenderFrameBuilder::new(pipeline_id);
let root_scroll_layer_id = frame_builder.next_scroll_layer_id(); let root_scroll_layer_id = frame_builder.next_scroll_layer_id();
let sc_id = rw_data.display_list.as_ref().unwrap().convert_to_webrender( let sc_id = rw_data.display_list.as_ref().unwrap().convert_to_webrender(
webrender_api, &mut self.webrender_api,
pipeline_id, pipeline_id,
epoch, epoch,
Some(root_scroll_layer_id), Some(root_scroll_layer_id),
&mut frame_builder); &mut frame_builder);
let root_background_color = get_root_flow_background_color(layout_root); let root_background_color = get_root_flow_background_color(layout_root);
let root_background_color = let root_background_color =
webrender_traits::ColorF::new(root_background_color.r, webrender_traits::ColorF::new(root_background_color.r,
root_background_color.g, root_background_color.g,
root_background_color.b, root_background_color.b,
root_background_color.a); root_background_color.a);
let viewport_size = Size2D::new(self.viewport_size.width.to_f32_px(), let viewport_size = Size2D::new(self.viewport_size.width.to_f32_px(),
self.viewport_size.height.to_f32_px()); self.viewport_size.height.to_f32_px());
webrender_api.set_root_stacking_context( self.webrender_api.set_root_stacking_context(sc_id,
sc_id, root_background_color,
root_background_color, epoch,
epoch, pipeline_id,
pipeline_id, viewport_size,
viewport_size, frame_builder.stacking_contexts,
frame_builder.stacking_contexts, frame_builder.display_lists,
frame_builder.display_lists, frame_builder.auxiliary_lists_builder.finalize());
frame_builder.auxiliary_lists_builder.finalize());
} else {
self.paint_chan
.send(LayoutToPaintMsg::PaintInit(self.epoch, display_list))
.unwrap();
}
}); });
} }

View file

@ -15,7 +15,6 @@ script_traits = {path = "../script_traits"}
msg = {path = "../msg"} msg = {path = "../msg"}
net_traits = {path = "../net_traits"} net_traits = {path = "../net_traits"}
profile_traits = {path = "../profile_traits"} profile_traits = {path = "../profile_traits"}
util = {path = "../util"}
ipc-channel = "0.5" ipc-channel = "0.5"
url = {version = "1.2", features = ["heap_size"]} url = {version = "1.2", features = ["heap_size"]}

View file

@ -11,7 +11,6 @@ extern crate net_traits;
extern crate profile_traits; extern crate profile_traits;
extern crate script_traits; extern crate script_traits;
extern crate url; extern crate url;
extern crate util;
extern crate webrender_traits; extern crate webrender_traits;
// This module contains traits in layout used generically // This module contains traits in layout used generically
@ -20,7 +19,6 @@ extern crate webrender_traits;
// that these modules won't have to depend on layout. // that these modules won't have to depend on layout.
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use gfx::paint_thread::LayoutToPaintMsg;
use ipc_channel::ipc::{IpcReceiver, IpcSender}; use ipc_channel::ipc::{IpcReceiver, IpcSender};
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use net_traits::image_cache_thread::ImageCacheThread; use net_traits::image_cache_thread::ImageCacheThread;
@ -29,7 +27,6 @@ use script_traits::{ConstellationControlMsg, LayoutControlMsg};
use script_traits::LayoutMsg as ConstellationMsg; use script_traits::LayoutMsg as ConstellationMsg;
use std::sync::mpsc::{Receiver, Sender}; use std::sync::mpsc::{Receiver, Sender};
use url::Url; use url::Url;
use util::ipc::OptionalIpcSender;
// A static method creating a layout thread // A static method creating a layout thread
// Here to remove the compositor -> layout dependency // Here to remove the compositor -> layout dependency
@ -42,12 +39,11 @@ pub trait LayoutThreadFactory {
pipeline_port: IpcReceiver<LayoutControlMsg>, pipeline_port: IpcReceiver<LayoutControlMsg>,
constellation_chan: IpcSender<ConstellationMsg>, constellation_chan: IpcSender<ConstellationMsg>,
script_chan: IpcSender<ConstellationControlMsg>, script_chan: IpcSender<ConstellationControlMsg>,
layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
image_cache_thread: ImageCacheThread, image_cache_thread: ImageCacheThread,
font_cache_thread: FontCacheThread, font_cache_thread: FontCacheThread,
time_profiler_chan: time::ProfilerChan, time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan, mem_profiler_chan: mem::ProfilerChan,
content_process_shutdown_chan: IpcSender<()>, content_process_shutdown_chan: IpcSender<()>,
webrender_api_sender: Option<webrender_traits::RenderApiSender>, webrender_api_sender: webrender_traits::RenderApiSender,
layout_threads: usize); layout_threads: usize);
} }

View file

@ -252,8 +252,8 @@ struct ImageCache {
// The placeholder image used when an image fails to load // The placeholder image used when an image fails to load
placeholder_image: Option<Arc<Image>>, placeholder_image: Option<Arc<Image>>,
// Webrender API instance, if enabled. // Webrender API instance.
webrender_api: Option<webrender_traits::RenderApi>, webrender_api: webrender_traits::RenderApi,
} }
/// Message that the decoder worker threads send to main image cache thread. /// Message that the decoder worker threads send to main image cache thread.
@ -318,24 +318,23 @@ impl LoadOrigin for ImageCacheOrigin {
} }
} }
fn get_placeholder_image(webrender_api: &Option<webrender_traits::RenderApi>) -> io::Result<Arc<Image>> { fn get_placeholder_image(webrender_api: &webrender_traits::RenderApi) -> io::Result<Arc<Image>> {
let mut placeholder_path = try!(resources_dir_path()); let mut placeholder_path = try!(resources_dir_path());
placeholder_path.push("rippy.png"); placeholder_path.push("rippy.png");
let mut file = try!(File::open(&placeholder_path)); let mut file = try!(File::open(&placeholder_path));
let mut image_data = vec![]; let mut image_data = vec![];
try!(file.read_to_end(&mut image_data)); try!(file.read_to_end(&mut image_data));
let mut image = load_from_memory(&image_data).unwrap(); let mut image = load_from_memory(&image_data).unwrap();
if let Some(ref webrender_api) = *webrender_api { let format = convert_format(image.format);
let format = convert_format(image.format); let mut bytes = Vec::new();
let mut bytes = Vec::new(); bytes.extend_from_slice(&*image.bytes);
bytes.extend_from_slice(&*image.bytes); image.id = Some(webrender_api.add_image(image.width, image.height, format, bytes));
image.id = Some(webrender_api.add_image(image.width, image.height, format, bytes));
}
Ok(Arc::new(image)) Ok(Arc::new(image))
} }
impl ImageCache { impl ImageCache {
fn run(core_resource_thread: CoreResourceThread, fn run(core_resource_thread: CoreResourceThread,
webrender_api: Option<webrender_traits::RenderApi>, webrender_api: webrender_traits::RenderApi,
ipc_command_receiver: IpcReceiver<ImageCacheCommand>) { ipc_command_receiver: IpcReceiver<ImageCacheCommand>) {
// Preload the placeholder image, used when images fail to load. // Preload the placeholder image, used when images fail to load.
let placeholder_image = get_placeholder_image(&webrender_api).ok(); let placeholder_image = get_placeholder_image(&webrender_api).ok();
@ -479,16 +478,14 @@ impl ImageCache {
fn complete_load(&mut self, key: LoadKey, mut load_result: LoadResult) { fn complete_load(&mut self, key: LoadKey, mut load_result: LoadResult) {
let pending_load = self.pending_loads.remove(&key).unwrap(); let pending_load = self.pending_loads.remove(&key).unwrap();
if let Some(ref webrender_api) = self.webrender_api { match load_result {
match load_result { LoadResult::Loaded(ref mut image) => {
LoadResult::Loaded(ref mut image) => { let format = convert_format(image.format);
let format = convert_format(image.format); let mut bytes = Vec::new();
let mut bytes = Vec::new(); bytes.extend_from_slice(&*image.bytes);
bytes.extend_from_slice(&*image.bytes); image.id = Some(self.webrender_api.add_image(image.width, image.height, format, bytes));
image.id = Some(webrender_api.add_image(image.width, image.height, format, bytes));
}
LoadResult::PlaceholderLoaded(..) | LoadResult::None => {}
} }
LoadResult::PlaceholderLoaded(..) | LoadResult::None => {}
} }
let image_response = match load_result { let image_response = match load_result {
@ -627,7 +624,7 @@ impl ImageCache {
/// Create a new image cache. /// Create a new image cache.
pub fn new_image_cache_thread(core_resource_thread: CoreResourceThread, pub fn new_image_cache_thread(core_resource_thread: CoreResourceThread,
webrender_api: Option<webrender_traits::RenderApi>) -> ImageCacheThread { webrender_api: webrender_traits::RenderApi) -> ImageCacheThread {
let (ipc_command_sender, ipc_command_receiver) = ipc::channel().unwrap(); let (ipc_command_sender, ipc_command_receiver) = ipc::channel().unwrap();
spawn_named("ImageCacheThread".to_owned(), move || { spawn_named("ImageCacheThread".to_owned(), move || {

View file

@ -4,7 +4,6 @@
use ipc_channel::ipc::IpcSharedMemory; use ipc_channel::ipc::IpcSharedMemory;
use piston_image::{self, DynamicImage, ImageFormat}; use piston_image::{self, DynamicImage, ImageFormat};
use util::opts;
pub use msg::constellation_msg::{Image, PixelFormat}; pub use msg::constellation_msg::{Image, PixelFormat};
@ -21,24 +20,14 @@ pub struct ImageMetadata {
fn byte_swap_and_premultiply(data: &mut [u8]) { fn byte_swap_and_premultiply(data: &mut [u8]) {
let length = data.len(); let length = data.len();
// No need to pre-multiply alpha when using direct GPU rendering.
let premultiply_alpha = !opts::get().use_webrender;
for i in (0..length).step_by(4) { for i in (0..length).step_by(4) {
let r = data[i + 2]; let r = data[i + 2];
let g = data[i + 1]; let g = data[i + 1];
let b = data[i + 0]; let b = data[i + 0];
let a = data[i + 3];
if premultiply_alpha { data[i + 0] = r;
data[i + 0] = ((r as u32) * (a as u32) / 255) as u8; data[i + 1] = g;
data[i + 1] = ((g as u32) * (a as u32) / 255) as u8; data[i + 2] = b;
data[i + 2] = ((b as u32) * (a as u32) / 255) as u8;
} else {
data[i + 0] = r;
data[i + 1] = g;
data[i + 2] = b;
}
} }
} }

View file

@ -5,7 +5,7 @@
use canvas_traits::{Canvas2dMsg, CanvasCommonMsg, CanvasMsg}; use canvas_traits::{Canvas2dMsg, CanvasCommonMsg, CanvasMsg};
use canvas_traits::{CompositionOrBlending, FillOrStrokeStyle, FillRule}; use canvas_traits::{CompositionOrBlending, FillOrStrokeStyle, FillRule};
use canvas_traits::{LineCapStyle, LineJoinStyle, LinearGradientStyle}; use canvas_traits::{LineCapStyle, LineJoinStyle, LinearGradientStyle};
use canvas_traits::{RadialGradientStyle, RepetitionStyle, byte_swap, byte_swap_and_premultiply}; use canvas_traits::{RadialGradientStyle, RepetitionStyle, byte_swap_and_premultiply};
use cssparser::{Parser, RGBA}; use cssparser::{Parser, RGBA};
use cssparser::Color as CSSColor; use cssparser::Color as CSSColor;
use dom::bindings::cell::DOMRefCell; use dom::bindings::cell::DOMRefCell;
@ -47,7 +47,6 @@ use std::cell::Cell;
use std::str::FromStr; use std::str::FromStr;
use unpremultiplytable::UNPREMULTIPLY_TABLE; use unpremultiplytable::UNPREMULTIPLY_TABLE;
use url::Url; use url::Url;
use util::opts;
#[must_root] #[must_root]
#[derive(JSTraceable, Clone, HeapSizeOf)] #[derive(JSTraceable, Clone, HeapSizeOf)]
@ -297,14 +296,7 @@ impl CanvasRenderingContext2D {
Some((mut data, size)) => { Some((mut data, size)) => {
// Pixels come from cache in BGRA order and drawImage expects RGBA so we // Pixels come from cache in BGRA order and drawImage expects RGBA so we
// have to swap the color values // have to swap the color values
if opts::get().use_webrender { byte_swap_and_premultiply(&mut data);
// Webrender doesn't pre-multiply alpha when decoding
// images, but canvas expects the images to be
// pre-multiplied alpha.
byte_swap_and_premultiply(&mut data);
} else {
byte_swap(&mut data);
}
let size = Size2D::new(size.width as f64, size.height as f64); let size = Size2D::new(size.width as f64, size.height as f64);
(data, size) (data, size)
}, },

View file

@ -1220,42 +1220,20 @@ impl Window {
} }
pub fn scroll_offset_query(&self, node: &Node) -> Point2D<f32> { pub fn scroll_offset_query(&self, node: &Node) -> Point2D<f32> {
// WebRender always keeps the scroll offsets up to date and stored here in the window. So, let mut node = Root::from_ref(node);
// if WR is in use, all we need to do is to check our list of scroll offsets and return the loop {
// result. if let Some(scroll_offset) = self.scroll_offsets
if opts::get().use_webrender { .borrow()
let mut node = Root::from_ref(node); .get(&node.to_untrusted_node_address()) {
loop { return *scroll_offset
if let Some(scroll_offset) = self.scroll_offsets }
.borrow() node = match node.GetParentNode() {
.get(&node.to_untrusted_node_address()) { Some(node) => node,
return *scroll_offset None => break,
}
node = match node.GetParentNode() {
Some(node) => node,
None => break,
}
} }
let offset = self.current_viewport.get().origin;
return Point2D::new(offset.x.to_f32_px(), offset.y.to_f32_px())
} }
let offset = self.current_viewport.get().origin;
let node = node.to_trusted_node_address(); Point2D::new(offset.x.to_f32_px(), offset.y.to_f32_px())
if !self.reflow(ReflowGoal::ForScriptQuery,
ReflowQueryType::NodeLayerIdQuery(node),
ReflowReason::Query) {
return Point2D::zero();
}
let layer_id = self.layout_rpc.node_layer_id().layer_id;
let (send, recv) = ipc::channel::<Point2D<f32>>().unwrap();
let global_scope = self.upcast::<GlobalScope>();
global_scope
.constellation_chan()
.send(ConstellationMsg::GetScrollOffset(global_scope.pipeline_id(), layer_id, send))
.unwrap();
recv.recv().unwrap_or(Point2D::zero())
} }
// https://drafts.csswg.org/cssom-view/#dom-element-scroll // https://drafts.csswg.org/cssom-view/#dom-element-scroll

View file

@ -1143,7 +1143,6 @@ impl ScriptThread {
new_pipeline_id, new_pipeline_id,
frame_type, frame_type,
load_data, load_data,
paint_chan,
pipeline_port, pipeline_port,
layout_to_constellation_chan, layout_to_constellation_chan,
content_process_shutdown_chan, content_process_shutdown_chan,
@ -1160,7 +1159,6 @@ impl ScriptThread {
layout_pair: layout_pair, layout_pair: layout_pair,
pipeline_port: pipeline_port, pipeline_port: pipeline_port,
constellation_chan: layout_to_constellation_chan, constellation_chan: layout_to_constellation_chan,
paint_chan: paint_chan,
script_chan: self.control_chan.clone(), script_chan: self.control_chan.clone(),
image_cache_thread: self.image_cache_thread.clone(), image_cache_thread: self.image_cache_thread.clone(),
content_process_shutdown_chan: content_process_shutdown_chan, content_process_shutdown_chan: content_process_shutdown_chan,

View file

@ -31,4 +31,3 @@ selectors = "0.13"
string_cache = {version = "0.2.26", features = ["heap_size"]} string_cache = {version = "0.2.26", features = ["heap_size"]}
style = {path = "../style"} style = {path = "../style"}
url = {version = "1.2", features = ["heap_size"]} url = {version = "1.2", features = ["heap_size"]}
util = {path = "../util"}

View file

@ -39,7 +39,6 @@ extern crate selectors;
extern crate string_cache; extern crate string_cache;
extern crate style; extern crate style;
extern crate url; extern crate url;
extern crate util;
pub mod message; pub mod message;
pub mod reporter; pub mod reporter;

View file

@ -21,7 +21,6 @@ use style::context::ReflowGoal;
use style::selector_impl::PseudoElement; use style::selector_impl::PseudoElement;
use style::stylesheets::Stylesheet; use style::stylesheets::Stylesheet;
use url::Url; use url::Url;
use util::ipc::OptionalOpaqueIpcSender;
/// Asynchronous messages that script can send to layout. /// Asynchronous messages that script can send to layout.
pub enum Msg { pub enum Msg {
@ -148,7 +147,6 @@ pub struct NewLayoutThreadInfo {
pub constellation_chan: IpcSender<ConstellationMsg>, pub constellation_chan: IpcSender<ConstellationMsg>,
pub script_chan: IpcSender<ConstellationControlMsg>, pub script_chan: IpcSender<ConstellationControlMsg>,
pub image_cache_thread: ImageCacheThread, pub image_cache_thread: ImageCacheThread,
pub paint_chan: OptionalOpaqueIpcSender,
pub content_process_shutdown_chan: IpcSender<()>, pub content_process_shutdown_chan: IpcSender<()>,
pub layout_threads: usize, pub layout_threads: usize,
} }

View file

@ -20,7 +20,6 @@ heapsize = "0.3.0"
heapsize_plugin = "0.1.2" heapsize_plugin = "0.1.2"
hyper_serde = "0.1.4" hyper_serde = "0.1.4"
ipc-channel = "0.5" ipc-channel = "0.5"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
libc = "0.2" libc = "0.2"
msg = {path = "../msg"} msg = {path = "../msg"}
net_traits = {path = "../net_traits"} net_traits = {path = "../net_traits"}
@ -33,4 +32,3 @@ serde_derive = "0.8"
style_traits = {path = "../style_traits", features = ["servo"]} style_traits = {path = "../style_traits", features = ["servo"]}
time = "0.1.12" time = "0.1.12"
url = {version = "1.2", features = ["heap_size"]} url = {version = "1.2", features = ["heap_size"]}
util = {path = "../util"}

View file

@ -20,7 +20,6 @@ extern crate gfx_traits;
extern crate heapsize; extern crate heapsize;
extern crate hyper_serde; extern crate hyper_serde;
extern crate ipc_channel; extern crate ipc_channel;
extern crate layers;
extern crate libc; extern crate libc;
extern crate msg; extern crate msg;
extern crate net_traits; extern crate net_traits;
@ -33,7 +32,6 @@ extern crate serde_derive;
extern crate style_traits; extern crate style_traits;
extern crate time; extern crate time;
extern crate url; extern crate url;
extern crate util;
mod script_msg; mod script_msg;
pub mod webdriver_msg; pub mod webdriver_msg;
@ -46,12 +44,12 @@ use euclid::point::Point2D;
use euclid::rect::Rect; use euclid::rect::Rect;
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D; use euclid::size::TypedSize2D;
use gfx_traits::DevicePixel;
use gfx_traits::Epoch; use gfx_traits::Epoch;
use gfx_traits::LayerId; use gfx_traits::LayerId;
use gfx_traits::StackingContextId; use gfx_traits::StackingContextId;
use heapsize::HeapSizeOf; use heapsize::HeapSizeOf;
use ipc_channel::ipc::{IpcReceiver, IpcSender}; use ipc_channel::ipc::{IpcReceiver, IpcSender};
use layers::geometry::DevicePixel;
use libc::c_void; use libc::c_void;
use msg::constellation_msg::{FrameId, FrameType, Image, Key, KeyModifiers, KeyState, LoadData}; use msg::constellation_msg::{FrameId, FrameType, Image, Key, KeyModifiers, KeyState, LoadData};
use msg::constellation_msg::{PipelineId, PipelineNamespaceId, ReferrerPolicy}; use msg::constellation_msg::{PipelineId, PipelineNamespaceId, ReferrerPolicy};
@ -68,7 +66,6 @@ use std::fmt;
use std::sync::mpsc::{Receiver, Sender}; use std::sync::mpsc::{Receiver, Sender};
use style_traits::{PagePx, UnsafeNode, ViewportPx}; use style_traits::{PagePx, UnsafeNode, ViewportPx};
use url::Url; use url::Url;
use util::ipc::OptionalOpaqueIpcSender;
use webdriver_msg::{LoadStatus, WebDriverScriptCommand}; use webdriver_msg::{LoadStatus, WebDriverScriptCommand};
pub use script_msg::{LayoutMsg, ScriptMsg, EventResult, LogEntry}; pub use script_msg::{LayoutMsg, ScriptMsg, EventResult, LogEntry};
@ -138,9 +135,6 @@ pub struct NewLayoutInfo {
pub frame_type: FrameType, pub frame_type: FrameType,
/// Network request data which will be initiated by the script thread. /// Network request data which will be initiated by the script thread.
pub load_data: LoadData, pub load_data: LoadData,
/// The paint channel, cast to `OptionalOpaqueIpcSender`. This is really an
/// `Sender<LayoutToPaintMsg>`.
pub paint_chan: OptionalOpaqueIpcSender,
/// A port on which layout can receive messages from the pipeline. /// A port on which layout can receive messages from the pipeline.
pub pipeline_port: IpcReceiver<LayoutControlMsg>, pub pipeline_port: IpcReceiver<LayoutControlMsg>,
/// A sender for the layout thread to communicate to the constellation. /// A sender for the layout thread to communicate to the constellation.

View file

@ -128,8 +128,6 @@ pub enum ScriptMsg {
ResizeTo(Size2D<u32>), ResizeTo(Size2D<u32>),
/// Script has handled a touch event, and either prevented or allowed default actions. /// Script has handled a touch event, and either prevented or allowed default actions.
TouchEventProcessed(EventResult), TouchEventProcessed(EventResult),
/// Get Scroll Offset
GetScrollOffset(PipelineId, LayerId, IpcSender<Point2D<f32>>),
/// A log entry, with the pipeline id and thread name /// A log entry, with the pipeline id and thread name
LogEntry(Option<PipelineId>, Option<String>, LogEntry), LogEntry(Option<PipelineId>, Option<String>, LogEntry),
/// Notifies the constellation that this pipeline has exited. /// Notifies the constellation that this pipeline has exited.

View file

@ -321,14 +321,11 @@ dependencies = [
name = "compositing" name = "compositing"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"azure 0.9.0 (git+https://github.com/servo/rust-azure)",
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1", "gfx_traits 0.0.1",
"gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
"net_traits 0.0.1", "net_traits 0.0.1",
@ -359,7 +356,6 @@ dependencies = [
"gfx 0.0.1", "gfx 0.0.1",
"gfx_traits 0.0.1", "gfx_traits 0.0.1",
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"layout_traits 0.0.1", "layout_traits 0.0.1",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
@ -797,7 +793,6 @@ dependencies = [
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -806,8 +801,6 @@ dependencies = [
"net_traits 0.0.1", "net_traits 0.0.1",
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"profile_traits 0.0.1",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"range 0.0.1", "range 0.0.1",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -841,13 +834,9 @@ name = "gfx_traits"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"azure 0.9.0 (git+https://github.com/servo/rust-azure)", "azure 0.9.0 (git+https://github.com/servo/rust-azure)",
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"msg 0.0.1",
"plugins 0.0.1", "plugins 0.0.1",
"profile_traits 0.0.1",
"range 0.0.1", "range 0.0.1",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -894,8 +883,8 @@ dependencies = [
"compositing 0.0.1", "compositing 0.0.1",
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
"net_traits 0.0.1", "net_traits 0.0.1",
@ -1140,26 +1129,6 @@ name = "language-tags"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "layers"
version = "0.5.3"
source = "git+https://github.com/servo/rust-layers#b064de859b2cf3f4e07b29ee11a34543f1671ac0"
dependencies = [
"cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"glx 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"io-surface 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-skia 0.20130412.24 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "layout" name = "layout"
version = "0.0.1" version = "0.0.1"
@ -1250,7 +1219,6 @@ dependencies = [
"profile_traits 0.0.1", "profile_traits 0.0.1",
"script_traits 0.0.1", "script_traits 0.0.1",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"webrender_traits 0.6.0 (git+https://github.com/servo/webrender)", "webrender_traits 0.6.0 (git+https://github.com/servo/webrender)",
] ]
@ -2049,7 +2017,6 @@ dependencies = [
"string_cache 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
] ]
[[package]] [[package]]
@ -2076,7 +2043,6 @@ dependencies = [
"heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
"net_traits 0.0.1", "net_traits 0.0.1",
@ -2089,7 +2055,6 @@ dependencies = [
"style_traits 0.0.1", "style_traits 0.0.1",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
] ]
[[package]] [[package]]
@ -2916,7 +2881,6 @@ dependencies = [
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09c9d3760673c427d46f91a0350f0a84a52e6bc5a84adf26dc610b6c52436630" "checksum khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09c9d3760673c427d46f91a0350f0a84a52e6bc5a84adf26dc610b6c52436630"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum layers 0.5.3 (git+https://github.com/servo/rust-layers)" = "<none>"
"checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" "checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417"
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f" "checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
"checksum leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd100e01f1154f2908dfa7d02219aeab25d0b9c7fa955164192e3245255a0c73" "checksum leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd100e01f1154f2908dfa7d02219aeab25d0b9c7fa955164192e3245255a0c73"

View file

@ -133,57 +133,50 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {
devtools::start_server(port) devtools::start_server(port)
}); });
let (webrender, webrender_api_sender) = if opts::get().use_webrender { let mut resource_path = resources_dir_path().unwrap();
if let Ok(mut resource_path) = resources_dir_path() { resource_path.push("shaders");
resource_path.push("shaders");
// TODO(gw): Duplicates device_pixels_per_screen_px from compositor. Tidy up! let (webrender, webrender_api_sender) = {
let scale_factor = window.scale_factor().get(); // TODO(gw): Duplicates device_pixels_per_screen_px from compositor. Tidy up!
let device_pixel_ratio = match opts.device_pixels_per_px { let scale_factor = window.scale_factor().get();
Some(device_pixels_per_px) => device_pixels_per_px, let device_pixel_ratio = match opts.device_pixels_per_px {
None => match opts.output_file { Some(device_pixels_per_px) => device_pixels_per_px,
Some(_) => 1.0, None => match opts.output_file {
None => scale_factor, Some(_) => 1.0,
} None => scale_factor,
}; }
};
let renderer_kind = if opts::get().should_use_osmesa() { let renderer_kind = if opts::get().should_use_osmesa() {
webrender_traits::RendererKind::OSMesa webrender_traits::RendererKind::OSMesa
} else {
webrender_traits::RendererKind::Native
};
let (webrender, webrender_sender) =
webrender::Renderer::new(webrender::RendererOptions {
device_pixel_ratio: device_pixel_ratio,
resource_path: resource_path,
enable_aa: opts.enable_text_antialiasing,
enable_msaa: opts.use_msaa,
enable_profiler: opts.webrender_stats,
debug: opts.webrender_debug,
enable_recording: false,
precache_shaders: opts.precache_shaders,
enable_scrollbars: opts.output_file.is_none(),
renderer_kind: renderer_kind,
});
(Some(webrender), Some(webrender_sender))
} else { } else {
(None, None) webrender_traits::RendererKind::Native
} };
} else {
(None, None) webrender::Renderer::new(webrender::RendererOptions {
device_pixel_ratio: device_pixel_ratio,
resource_path: resource_path,
enable_aa: opts.enable_text_antialiasing,
enable_msaa: opts.use_msaa,
enable_profiler: opts.webrender_stats,
debug: opts.webrender_debug,
enable_recording: false,
precache_shaders: opts.precache_shaders,
enable_scrollbars: opts.output_file.is_none(),
renderer_kind: renderer_kind,
})
}; };
// Create the constellation, which maintains the engine // Create the constellation, which maintains the engine
// pipelines, including the script and layout threads, as well // pipelines, including the script and layout threads, as well
// as the navigation context. // as the navigation context.
let (constellation_chan, sw_senders) = create_constellation(opts.clone(), let (constellation_chan, sw_senders) = create_constellation(opts.clone(),
compositor_proxy.clone_compositor_proxy(), compositor_proxy.clone_compositor_proxy(),
time_profiler_chan.clone(), time_profiler_chan.clone(),
mem_profiler_chan.clone(), mem_profiler_chan.clone(),
devtools_chan, devtools_chan,
supports_clipboard, supports_clipboard,
webrender_api_sender.clone()); webrender_api_sender.clone());
// Send the constellation's swmanager sender to service worker manager thread // Send the constellation's swmanager sender to service worker manager thread
script::init(sw_senders); script::init(sw_senders);
@ -247,7 +240,7 @@ fn create_constellation(opts: opts::Opts,
mem_profiler_chan: mem::ProfilerChan, mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<Sender<devtools_traits::DevtoolsControlMsg>>, devtools_chan: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
supports_clipboard: bool, supports_clipboard: bool,
webrender_api_sender: Option<webrender_traits::RenderApiSender>) webrender_api_sender: webrender_traits::RenderApiSender)
-> (Sender<ConstellationMsg>, SWManagerSenders) { -> (Sender<ConstellationMsg>, SWManagerSenders) {
let bluetooth_thread: IpcSender<BluetoothMethodMsg> = BluetoothThreadFactory::new(); let bluetooth_thread: IpcSender<BluetoothMethodMsg> = BluetoothThreadFactory::new();
@ -257,9 +250,9 @@ fn create_constellation(opts: opts::Opts,
time_profiler_chan.clone(), time_profiler_chan.clone(),
opts.config_dir.map(Into::into)); opts.config_dir.map(Into::into));
let image_cache_thread = new_image_cache_thread(public_resource_threads.sender(), let image_cache_thread = new_image_cache_thread(public_resource_threads.sender(),
webrender_api_sender.as_ref().map(|wr| wr.create_api())); webrender_api_sender.create_api());
let font_cache_thread = FontCacheThread::new(public_resource_threads.sender(), let font_cache_thread = FontCacheThread::new(public_resource_threads.sender(),
webrender_api_sender.as_ref().map(|wr| wr.create_api())); Some(webrender_api_sender.create_api()));
let resource_sender = public_resource_threads.sender(); let resource_sender = public_resource_threads.sender();

View file

@ -192,9 +192,6 @@ pub struct Opts {
/// Enable vsync in the compositor /// Enable vsync in the compositor
pub enable_vsync: bool, pub enable_vsync: bool,
/// True to enable the webrender painting/compositing backend.
pub use_webrender: bool,
/// True to show webrender profiling stats on screen. /// True to show webrender profiling stats on screen.
pub webrender_stats: bool, pub webrender_stats: bool,
@ -212,9 +209,6 @@ pub struct Opts {
/// Directory for a default config directory /// Directory for a default config directory
pub config_dir: Option<String>, pub config_dir: Option<String>,
// Which rendering API to use.
pub render_api: RenderApi,
// don't skip any backtraces on panic // don't skip any backtraces on panic
pub full_backtraces: bool, pub full_backtraces: bool,
@ -452,15 +446,6 @@ enum UserAgent {
Android, Android,
} }
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
pub enum RenderApi {
GL,
ES2,
}
const DEFAULT_RENDER_API: RenderApi = RenderApi::GL;
fn default_user_agent_string(agent: UserAgent) -> &'static str { fn default_user_agent_string(agent: UserAgent) -> &'static str {
#[cfg(all(target_os = "linux", target_arch = "x86_64"))] #[cfg(all(target_os = "linux", target_arch = "x86_64"))]
const DESKTOP_UA_STRING: &'static str = const DESKTOP_UA_STRING: &'static str =
@ -549,10 +534,8 @@ pub fn default_opts() -> Opts {
exit_after_load: false, exit_after_load: false,
no_native_titlebar: false, no_native_titlebar: false,
enable_vsync: true, enable_vsync: true,
use_webrender: true,
webrender_stats: false, webrender_stats: false,
use_msaa: false, use_msaa: false,
render_api: DEFAULT_RENDER_API,
config_dir: None, config_dir: None,
full_backtraces: false, full_backtraces: false,
is_printing_version: false, is_printing_version: false,
@ -800,15 +783,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
opt_match.opt_present("b") || opt_match.opt_present("b") ||
!PREFS.get("shell.native-titlebar.enabled").as_boolean().unwrap(); !PREFS.get("shell.native-titlebar.enabled").as_boolean().unwrap();
let use_webrender = !opt_match.opt_present("c");
let render_api = match opt_match.opt_str("G") {
Some(ref ga) if ga == "gl" => RenderApi::GL,
Some(ref ga) if ga == "es2" => RenderApi::ES2,
None => DEFAULT_RENDER_API,
_ => args_fail(&format!("error: graphics option must be gl or es2:")),
};
let is_printing_version = opt_match.opt_present("v") || opt_match.opt_present("version"); let is_printing_version = opt_match.opt_present("v") || opt_match.opt_present("version");
let opts = Opts { let opts = Opts {
@ -842,7 +816,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
sandbox: opt_match.opt_present("S"), sandbox: opt_match.opt_present("S"),
random_pipeline_closure_probability: random_pipeline_closure_probability, random_pipeline_closure_probability: random_pipeline_closure_probability,
random_pipeline_closure_seed: random_pipeline_closure_seed, random_pipeline_closure_seed: random_pipeline_closure_seed,
render_api: render_api,
show_debug_borders: debug_options.show_compositor_borders, show_debug_borders: debug_options.show_compositor_borders,
show_debug_fragment_borders: debug_options.show_fragment_borders, show_debug_fragment_borders: debug_options.show_fragment_borders,
show_debug_parallel_paint: debug_options.show_parallel_paint, show_debug_parallel_paint: debug_options.show_parallel_paint,
@ -862,7 +835,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
exit_after_load: opt_match.opt_present("x"), exit_after_load: opt_match.opt_present("x"),
no_native_titlebar: do_not_use_native_titlebar, no_native_titlebar: do_not_use_native_titlebar,
enable_vsync: !debug_options.disable_vsync, enable_vsync: !debug_options.disable_vsync,
use_webrender: use_webrender,
webrender_stats: debug_options.webrender_stats, webrender_stats: debug_options.webrender_stats,
use_msaa: debug_options.use_msaa, use_msaa: debug_options.use_msaa,
config_dir: opt_match.opt_str("config-dir"), config_dir: opt_match.opt_str("config-dir"),

40
ports/cef/Cargo.lock generated
View file

@ -6,9 +6,9 @@ dependencies = [
"compositing 0.0.1", "compositing 0.0.1",
"devtools 0.0.1", "devtools 0.0.1",
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin_app 0.0.1", "glutin_app 0.0.1",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
@ -278,14 +278,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "compositing" name = "compositing"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"azure 0.9.0 (git+https://github.com/servo/rust-azure)",
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1", "gfx_traits 0.0.1",
"gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
"net_traits 0.0.1", "net_traits 0.0.1",
@ -316,7 +313,6 @@ dependencies = [
"gfx 0.0.1", "gfx 0.0.1",
"gfx_traits 0.0.1", "gfx_traits 0.0.1",
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"layout_traits 0.0.1", "layout_traits 0.0.1",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
@ -713,7 +709,6 @@ dependencies = [
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -722,8 +717,6 @@ dependencies = [
"net_traits 0.0.1", "net_traits 0.0.1",
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"profile_traits 0.0.1",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"range 0.0.1", "range 0.0.1",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -748,13 +741,9 @@ name = "gfx_traits"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"azure 0.9.0 (git+https://github.com/servo/rust-azure)", "azure 0.9.0 (git+https://github.com/servo/rust-azure)",
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"msg 0.0.1",
"plugins 0.0.1", "plugins 0.0.1",
"profile_traits 0.0.1",
"range 0.0.1", "range 0.0.1",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -801,8 +790,8 @@ dependencies = [
"compositing 0.0.1", "compositing 0.0.1",
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
"net_traits 0.0.1", "net_traits 0.0.1",
@ -1047,26 +1036,6 @@ name = "language-tags"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "layers"
version = "0.5.3"
source = "git+https://github.com/servo/rust-layers#b064de859b2cf3f4e07b29ee11a34543f1671ac0"
dependencies = [
"cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"glx 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"io-surface 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-skia 0.20130412.24 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "layout" name = "layout"
version = "0.0.1" version = "0.0.1"
@ -1150,7 +1119,6 @@ dependencies = [
"profile_traits 0.0.1", "profile_traits 0.0.1",
"script_traits 0.0.1", "script_traits 0.0.1",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"webrender_traits 0.6.0 (git+https://github.com/servo/webrender)", "webrender_traits 0.6.0 (git+https://github.com/servo/webrender)",
] ]
@ -1900,7 +1868,6 @@ dependencies = [
"string_cache 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
] ]
[[package]] [[package]]
@ -1917,7 +1884,6 @@ dependencies = [
"heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_plugin 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.5.3 (git+https://github.com/servo/rust-layers)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
"net_traits 0.0.1", "net_traits 0.0.1",
@ -1930,7 +1896,6 @@ dependencies = [
"style_traits 0.0.1", "style_traits 0.0.1",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
] ]
[[package]] [[package]]
@ -2768,7 +2733,6 @@ dependencies = [
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09c9d3760673c427d46f91a0350f0a84a52e6bc5a84adf26dc610b6c52436630" "checksum khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09c9d3760673c427d46f91a0350f0a84a52e6bc5a84adf26dc610b6c52436630"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum layers 0.5.3 (git+https://github.com/servo/rust-layers)" = "<none>"
"checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" "checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417"
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f" "checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
"checksum leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd100e01f1154f2908dfa7d02219aeab25d0b9c7fa955164192e3245255a0c73" "checksum leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd100e01f1154f2908dfa7d02219aeab25d0b9c7fa955164192e3245255a0c73"

View file

@ -18,9 +18,9 @@ opt-level = 3
compositing = {path = "../../components/compositing"} compositing = {path = "../../components/compositing"}
devtools = {path = "../../components/devtools"} devtools = {path = "../../components/devtools"}
euclid = "0.10.1" euclid = "0.10.1"
gfx_traits = {path = "../../components/gfx_traits"}
gleam = "0.2.8" gleam = "0.2.8"
glutin_app = {path = "../glutin"} glutin_app = {path = "../glutin"}
layers = {git = "https://github.com/servo/rust-layers"}
libc = "0.2" libc = "0.2"
log = {version = "0.3.5", features = ["release_max_level_info"]} log = {version = "0.3.5", features = ["release_max_level_info"]}
msg = {path = "../../components/msg"} msg = {path = "../../components/msg"}

View file

@ -19,9 +19,9 @@ extern crate servo;
extern crate compositing; extern crate compositing;
extern crate euclid; extern crate euclid;
extern crate gfx_traits;
extern crate gleam; extern crate gleam;
extern crate glutin_app; extern crate glutin_app;
extern crate layers;
extern crate rustc_unicode; extern crate rustc_unicode;
extern crate script_traits; extern crate script_traits;

View file

@ -23,9 +23,8 @@ use compositing::windowing::{WindowEvent, WindowMethods};
use euclid::point::Point2D; use euclid::point::Point2D;
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
use euclid::size::{Size2D, TypedSize2D}; use euclid::size::{Size2D, TypedSize2D};
use gfx_traits::DevicePixel;
use gleam::gl; use gleam::gl;
use layers::geometry::DevicePixel;
use layers::platform::surface::NativeDisplay;
use msg::constellation_msg::{Key, KeyModifiers}; use msg::constellation_msg::{Key, KeyModifiers};
use net_traits::net_error_list::NetError; use net_traits::net_error_list::NetError;
use std::cell::RefCell; use std::cell::RefCell;
@ -284,19 +283,6 @@ impl WindowMethods for Window {
} }
} }
#[cfg(target_os="linux")]
fn native_display(&self) -> NativeDisplay {
use x11::xlib;
unsafe {
NativeDisplay::new(DISPLAY as *mut xlib::Display)
}
}
#[cfg(not(target_os="linux"))]
fn native_display(&self) -> NativeDisplay {
NativeDisplay::new()
}
fn create_compositor_channel(&self) fn create_compositor_channel(&self)
-> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) { -> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) {
let (sender, receiver) = channel(); let (sender, receiver) = channel();

View file

@ -12,8 +12,8 @@ path = "lib.rs"
bitflags = "0.7" bitflags = "0.7"
compositing = {path = "../../components/compositing"} compositing = {path = "../../components/compositing"}
euclid = "0.10.1" euclid = "0.10.1"
gfx_traits = {path = "../../components/gfx_traits"}
gleam = "0.2.8" gleam = "0.2.8"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
log = "0.3.5" log = "0.3.5"
msg = {path = "../../components/msg"} msg = {path = "../../components/msg"}
net_traits = {path = "../../components/net_traits"} net_traits = {path = "../../components/net_traits"}

View file

@ -11,9 +11,9 @@ extern crate compositing;
#[allow(unused_extern_crates)] #[allow(unused_extern_crates)]
#[cfg(target_os = "android")] extern crate egl; #[cfg(target_os = "android")] extern crate egl;
extern crate euclid; extern crate euclid;
extern crate gfx_traits;
extern crate gleam; extern crate gleam;
extern crate glutin; extern crate glutin;
extern crate layers;
#[macro_use] extern crate log; #[macro_use] extern crate log;
extern crate msg; extern crate msg;
extern crate net_traits; extern crate net_traits;
@ -22,7 +22,6 @@ extern crate script_traits;
extern crate style_traits; extern crate style_traits;
extern crate url; extern crate url;
extern crate util; extern crate util;
#[cfg(target_os = "linux")] extern crate x11;
#[cfg(target_os = "windows")] extern crate winapi; #[cfg(target_os = "windows")] extern crate winapi;
#[cfg(target_os = "windows")] extern crate user32; #[cfg(target_os = "windows")] extern crate user32;
#[cfg(target_os = "windows")] extern crate gdi32; #[cfg(target_os = "windows")] extern crate gdi32;

View file

@ -13,14 +13,13 @@ use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D; use euclid::size::TypedSize2D;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use gdi32; use gdi32;
use gfx_traits::DevicePixel;
use gleam::gl; use gleam::gl;
use glutin; use glutin;
use glutin::{Api, ElementState, Event, GlRequest, MouseButton, MouseScrollDelta, VirtualKeyCode}; use glutin::{Api, ElementState, Event, GlRequest, MouseButton, MouseScrollDelta, VirtualKeyCode};
use glutin::{ScanCode, TouchPhase}; use glutin::{ScanCode, TouchPhase};
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
use glutin::os::macos::{ActivationPolicy, WindowBuilderExt}; use glutin::os::macos::{ActivationPolicy, WindowBuilderExt};
use layers::geometry::DevicePixel;
use layers::platform::surface::NativeDisplay;
use msg::constellation_msg::{self, Key}; use msg::constellation_msg::{self, Key};
use msg::constellation_msg::{ALT, CONTROL, KeyState, NONE, SHIFT, SUPER}; use msg::constellation_msg::{ALT, CONTROL, KeyState, NONE, SHIFT, SUPER};
use net_traits::net_error_list::NetError; use net_traits::net_error_list::NetError;
@ -42,8 +41,6 @@ use url::Url;
use user32; use user32;
use util::geometry::ScreenPx; use util::geometry::ScreenPx;
use util::opts; use util::opts;
#[cfg(not(target_os = "android"))]
use util::opts::RenderApi;
use util::prefs::PREFS; use util::prefs::PREFS;
use util::resource_files; use util::resource_files;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -318,17 +315,7 @@ impl Window {
#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
fn gl_version() -> GlRequest { fn gl_version() -> GlRequest {
if opts::get().use_webrender { return GlRequest::Specific(Api::OpenGl, (3, 2));
return GlRequest::Specific(Api::OpenGl, (3, 2));
}
match opts::get().render_api {
RenderApi::GL => {
GlRequest::Specific(Api::OpenGl, (2, 1))
}
RenderApi::ES2 => {
GlRequest::Specific(Api::OpenGlEs, (2, 0))
}
}
} }
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))] #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
@ -558,72 +545,28 @@ impl Window {
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
fn handle_next_event(&self) -> bool { fn handle_next_event(&self) -> bool {
use std::thread; match self.kind {
use std::time::Duration; WindowKind::Window(ref window) => {
let event = match window.wait_events().next() {
// WebRender can use the normal blocking event check and proper vsync, None => {
// because it doesn't call X11 functions from another thread, so doesn't warn!("Window event stream closed.");
// hit the same issues explained below. return false;
if opts::get().use_webrender { },
match self.kind { Some(event) => event,
WindowKind::Window(ref window) => { };
let event = match window.wait_events().next() { let mut close = self.handle_window_event(event);
None => { if !close {
warn!("Window event stream closed."); while let Some(event) = window.poll_events().next() {
return false; if self.handle_window_event(event) {
}, close = true;
Some(event) => event, break
};
let mut close = self.handle_window_event(event);
if !close {
while let Some(event) = window.poll_events().next() {
if self.handle_window_event(event) {
close = true;
break
}
} }
} }
close
}
WindowKind::Headless(..) => {
false
} }
close
} }
} else { WindowKind::Headless(..) => {
// TODO(gw): This is an awful hack to work around the false
// broken way we currently call X11 from multiple threads.
//
// On some (most?) X11 implementations, blocking here
// with XPeekEvent results in the paint thread getting stuck
// in XGetGeometry randomly. When this happens the result
// is that until you trigger the XPeekEvent to return
// (by moving the mouse over the window) the paint thread
// never completes and you don't see the most recent
// results.
//
// For now, poll events and sleep for ~1 frame if there
// are no events. This means we don't spin the CPU at
// 100% usage, but is far from ideal!
//
// See https://github.com/servo/servo/issues/5780
//
match self.kind {
WindowKind::Window(ref window) => {
let first_event = window.poll_events().next();
match first_event {
Some(event) => {
self.handle_window_event(event)
}
None => {
thread::sleep(Duration::from_millis(16));
false
}
}
}
WindowKind::Headless(..) => {
false
}
} }
} }
} }
@ -1031,33 +974,6 @@ impl WindowMethods for Window {
true true
} }
#[cfg(target_os = "linux")]
fn native_display(&self) -> NativeDisplay {
use x11::xlib;
unsafe {
match opts::get().render_api {
RenderApi::GL => {
match self.kind {
WindowKind::Window(ref window) => {
NativeDisplay::new(window.platform_display() as *mut xlib::Display)
}
WindowKind::Headless(..) => {
unreachable!()
}
}
},
RenderApi::ES2 => {
NativeDisplay::new_egl_display()
}
}
}
}
#[cfg(not(target_os = "linux"))]
fn native_display(&self) -> NativeDisplay {
NativeDisplay::new()
}
/// Helper function to handle keyboard events. /// Helper function to handle keyboard events.
fn handle_key(&self, ch: Option<char>, key: Key, mods: constellation_msg::KeyModifiers) { fn handle_key(&self, ch: Option<char>, key: Key, mods: constellation_msg::KeyModifiers) {
match (mods, ch, key) { match (mods, ch, key) {