Auto merge of #9589 - glennw:webrender, r=pcwalton

Add WebRender integration to Servo.

WebRender is an experimental GPU accelerated rendering backend for Servo.

The WebRender backend can be specified by running Servo with the -w option (otherwise the default rendering backend will be used).

WebRender has many bugs, and missing features - but it is usable to browse most websites - please report any WebRender specific rendering bugs you encounter!

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9589)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-02-19 00:54:06 +05:30
commit ab07b06823
74 changed files with 2862 additions and 886 deletions

View file

@ -13,7 +13,7 @@
use app_units::{Au, AU_PER_PX};
use azure::azure_hl::Color;
use block::BlockFlow;
use canvas_traits::{CanvasMsg, FromLayoutMsg};
use canvas_traits::{CanvasMsg, CanvasPixelData, CanvasData, FromLayoutMsg};
use context::LayoutContext;
use euclid::num::Zero;
use euclid::{Matrix4, Point2D, Point3D, Rect, SideOffsets2D, Size2D};
@ -26,7 +26,7 @@ use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayIte
use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion};
use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayList, DisplayListSection};
use gfx::display_list::{GradientDisplayItem};
use gfx::display_list::{GradientStop, ImageDisplayItem, LayeredItem, LayerInfo};
use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGLDisplayItem, LayeredItem, LayerInfo};
use gfx::display_list::{LineDisplayItem, OpaqueNode, SolidColorDisplayItem};
use gfx::display_list::{StackingContext, TextDisplayItem, TextOrientation};
use gfx::paint_thread::THREAD_TINT_COLORS;
@ -51,8 +51,7 @@ use style::properties::style_structs::Border;
use style::properties::{self, ComputedValues};
use style::values::RGBA;
use style::values::computed;
use style::values::computed::LinearGradient;
use style::values::computed::{LengthOrNone, LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrNone, LengthOrPercentage, LengthOrPercentageOrAuto, LinearGradient};
use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
use style_traits::cursor::Cursor;
use table_cell::CollapsedBordersForCell;
@ -948,9 +947,12 @@ impl FragmentDisplayListBuilding for Fragment {
stacking_relative_flow_origin,
self);
if !stacking_relative_border_box.intersects(stacking_relative_display_port) {
debug!("Fragment::build_display_list: outside display port");
return
// 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
}
}
// Calculate the clip rect. If there's nothing to render at all, don't even construct
@ -1112,20 +1114,31 @@ impl FragmentDisplayListBuilding for Fragment {
}
SpecificFragmentInfo::Iframe(ref fragment_info) => {
if !stacking_relative_content_box.is_empty() {
let layer_id = self.layer_id();
display_list.content.push_back(DisplayItem::LayeredItemClass(box LayeredItem {
item: DisplayItem::NoopClass(
box BaseDisplayItem::new(&stacking_relative_content_box,
DisplayItemMetadata::new(self.node,
&*self.style,
Cursor::DefaultCursor),
clip)),
layer_id: layer_id
}));
if opts::get().use_webrender {
display_list.content.push_back(DisplayItem::IframeClass(box IframeDisplayItem {
base: BaseDisplayItem::new(&stacking_relative_content_box,
DisplayItemMetadata::new(self.node,
&*self.style,
Cursor::DefaultCursor),
clip),
iframe: fragment_info.pipeline_id,
}));
} else {
let layer_id = self.layer_id();
display_list.content.push_back(DisplayItem::LayeredItemClass(box LayeredItem {
item: DisplayItem::NoopClass(
box BaseDisplayItem::new(&stacking_relative_content_box,
DisplayItemMetadata::new(self.node,
&*self.style,
Cursor::DefaultCursor),
clip)),
layer_id: layer_id
}));
display_list.layer_info.push_back(LayerInfo::new(layer_id,
ScrollPolicy::Scrollable,
Some(fragment_info.pipeline_id)));
display_list.layer_info.push_back(LayerInfo::new(layer_id,
ScrollPolicy::Scrollable,
Some(fragment_info.pipeline_id)));
}
}
}
SpecificFragmentInfo::Image(ref mut image_fragment) => {
@ -1144,7 +1157,6 @@ impl FragmentDisplayListBuilding for Fragment {
}
}
SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
// TODO(ecoal95): make the canvas with a renderer use the custom layer
let width = canvas_fragment_info.replaced_image_fragment_info
.computed_inline_size.map_or(0, |w| w.to_px() as usize);
let height = canvas_fragment_info.replaced_image_fragment_info
@ -1156,7 +1168,7 @@ impl FragmentDisplayListBuilding for Fragment {
let ipc_renderer = ipc_renderer.lock().unwrap();
let (sender, receiver) = ipc::channel().unwrap();
ipc_renderer.send(CanvasMsg::FromLayout(
FromLayoutMsg::SendPixelContents(sender))).unwrap();
FromLayoutMsg::SendData(sender))).unwrap();
let data = receiver.recv().unwrap();
// Propagate the layer and the renderer to the paint thread.
@ -1165,31 +1177,54 @@ impl FragmentDisplayListBuilding for Fragment {
data
},
None => IpcSharedMemory::from_byte(0xFFu8, width * height * 4),
};
let display_item = DisplayItem::ImageClass(box ImageDisplayItem {
base: BaseDisplayItem::new(&stacking_relative_content_box,
DisplayItemMetadata::new(self.node,
&*self.style,
Cursor::DefaultCursor),
clip),
image: Arc::new(Image {
width: width as u32,
height: height as u32,
format: PixelFormat::RGBA8,
bytes: canvas_data,
None => CanvasData::Pixels(CanvasPixelData {
image_data: IpcSharedMemory::from_byte(0xFFu8, width * height * 4),
image_key: None,
}),
stretch_size: stacking_relative_content_box.size,
image_rendering: image_rendering::T::Auto,
});
};
display_list.content.push_back(DisplayItem::LayeredItemClass(box LayeredItem {
item: display_item,
layer_id: layer_id
}));
let display_item = match canvas_data {
CanvasData::Pixels(canvas_data) => {
DisplayItem::ImageClass(box ImageDisplayItem {
base: BaseDisplayItem::new(&stacking_relative_content_box,
DisplayItemMetadata::new(self.node,
&*self.style,
Cursor::DefaultCursor),
clip),
image: Arc::new(Image {
width: width as u32,
height: height as u32,
format: PixelFormat::RGBA8,
bytes: canvas_data.image_data,
id: canvas_data.image_key,
}),
stretch_size: stacking_relative_content_box.size,
image_rendering: image_rendering::T::Auto,
})
}
CanvasData::WebGL(context_id) => {
DisplayItem::WebGLClass(box WebGLDisplayItem {
base: BaseDisplayItem::new(&stacking_relative_content_box,
DisplayItemMetadata::new(self.node,
&*self.style,
Cursor::DefaultCursor),
clip),
context_id: context_id,
})
}
};
display_list.layer_info.push_back(
LayerInfo::new(layer_id, ScrollPolicy::Scrollable, None));
if opts::get().use_webrender {
display_list.content.push_back(display_item);
} else {
display_list.content.push_back(DisplayItem::LayeredItemClass(box LayeredItem {
item: display_item,
layer_id: layer_id
}));
display_list.layer_info.push_back(
LayerInfo::new(layer_id, ScrollPolicy::Scrollable, None));
}
}
}
SpecificFragmentInfo::UnscannedText(_) => {
@ -1993,4 +2028,3 @@ pub enum StackingContextCreationMode {
OuterScrollWrapper,
InnerScrollWrapper,
}