mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 17:25:36 +00:00
servo: Merge #9947 - Faster display list transfer (from pcwalton:faster-display-list-transfer); r=glennw
This series of commits improves performance of display list construction in browser.html by about 3x when using WebRender. It requires https://github.com/servo/webrender_traits/pull/18 and https://github.com/servo/webrender/pull/231. Anyone should feel free to review if they have time; I'll ask someone in particular once those two upstream commits land. cc @paulrouget Source-Repo: https://github.com/servo/servo Source-Revision: 187ca442337313a76ce115ac92a2da44d91d5b96
This commit is contained in:
parent
38a52325ef
commit
9a7523f50e
@ -24,8 +24,9 @@ use euclid::{Matrix2D, Matrix4, Point2D, Rect, SideOffsets2D, Size2D};
|
|||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
use gfx_traits::{LayerId, ScrollPolicy};
|
use gfx_traits::{LayerId, ScrollPolicy};
|
||||||
use heapsize::HeapSizeOf;
|
use heapsize::HeapSizeOf;
|
||||||
|
use ipc_channel::ipc::IpcSharedMemory;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use net_traits::image::base::Image;
|
use net_traits::image::base::{Image, PixelFormat};
|
||||||
use paint_context::PaintContext;
|
use paint_context::PaintContext;
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use serde::de::{self, Deserialize, Deserializer, MapVisitor, Visitor};
|
use serde::de::{self, Deserialize, Deserializer, MapVisitor, Visitor};
|
||||||
@ -46,7 +47,7 @@ use text::TextRun;
|
|||||||
use text::glyph::CharIndex;
|
use text::glyph::CharIndex;
|
||||||
use util::geometry::{self, MAX_RECT, ScreenPx};
|
use util::geometry::{self, MAX_RECT, ScreenPx};
|
||||||
use util::print_tree::PrintTree;
|
use util::print_tree::PrintTree;
|
||||||
use webrender_traits::WebGLContextId;
|
use webrender_traits::{self, WebGLContextId};
|
||||||
|
|
||||||
pub use style::dom::OpaqueNode;
|
pub use style::dom::OpaqueNode;
|
||||||
|
|
||||||
@ -986,8 +987,11 @@ pub enum TextOrientation {
|
|||||||
#[derive(Clone, HeapSizeOf, Deserialize, Serialize)]
|
#[derive(Clone, HeapSizeOf, Deserialize, Serialize)]
|
||||||
pub struct ImageDisplayItem {
|
pub struct ImageDisplayItem {
|
||||||
pub base: BaseDisplayItem,
|
pub base: BaseDisplayItem,
|
||||||
|
|
||||||
|
pub webrender_image: WebRenderImageInfo,
|
||||||
|
|
||||||
#[ignore_heap_size_of = "Because it is non-owning"]
|
#[ignore_heap_size_of = "Because it is non-owning"]
|
||||||
pub image: Arc<Image>,
|
pub image_data: Option<Arc<IpcSharedMemory>>,
|
||||||
|
|
||||||
/// The dimensions to which the image display item should be stretched. If this is smaller than
|
/// The dimensions to which the image display item should be stretched. If this is smaller than
|
||||||
/// the bounds of this display item, then the image will be repeated in the appropriate
|
/// the bounds of this display item, then the image will be repeated in the appropriate
|
||||||
@ -1203,10 +1207,14 @@ impl DisplayItem {
|
|||||||
|
|
||||||
DisplayItem::ImageClass(ref image_item) => {
|
DisplayItem::ImageClass(ref image_item) => {
|
||||||
debug!("Drawing image at {:?}.", image_item.base.bounds);
|
debug!("Drawing image at {:?}.", image_item.base.bounds);
|
||||||
paint_context.draw_image(&image_item.base.bounds,
|
paint_context.draw_image(
|
||||||
&image_item.stretch_size,
|
&image_item.base.bounds,
|
||||||
image_item.image.clone(),
|
&image_item.stretch_size,
|
||||||
image_item.image_rendering.clone());
|
&image_item.webrender_image,
|
||||||
|
&image_item.image_data
|
||||||
|
.as_ref()
|
||||||
|
.expect("Non-WR painting needs image data!")[..],
|
||||||
|
image_item.image_rendering.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayItem::WebGLClass(_) => {
|
DisplayItem::WebGLClass(_) => {
|
||||||
@ -1390,3 +1398,25 @@ impl StackingContextId {
|
|||||||
StackingContextId(fragment_type, id)
|
StackingContextId(fragment_type, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, HeapSizeOf, Deserialize, Serialize)]
|
||||||
|
pub struct WebRenderImageInfo {
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
pub format: PixelFormat,
|
||||||
|
#[ignore_heap_size_of = "WebRender traits type, and tiny"]
|
||||||
|
pub key: Option<webrender_traits::ImageKey>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebRenderImageInfo {
|
||||||
|
#[inline]
|
||||||
|
pub fn from_image(image: &Image) -> WebRenderImageInfo {
|
||||||
|
WebRenderImageInfo {
|
||||||
|
width: image.width,
|
||||||
|
height: image.height,
|
||||||
|
format: image.format,
|
||||||
|
key: image.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ use azure::{AzDrawTargetFillGlyphs, struct__AzGlyphBuffer, struct__AzPoint};
|
|||||||
use azure::{AzFloat, struct__AzDrawOptions, struct__AzGlyph};
|
use azure::{AzFloat, struct__AzDrawOptions, struct__AzGlyph};
|
||||||
use display_list::TextOrientation::{SidewaysLeft, SidewaysRight, Upright};
|
use display_list::TextOrientation::{SidewaysLeft, SidewaysRight, Upright};
|
||||||
use display_list::{BLUR_INFLATION_FACTOR, BorderRadii, BoxShadowClipMode, ClippingRegion};
|
use display_list::{BLUR_INFLATION_FACTOR, BorderRadii, BoxShadowClipMode, ClippingRegion};
|
||||||
use display_list::{TextDisplayItem};
|
use display_list::{TextDisplayItem, WebRenderImageInfo};
|
||||||
use euclid::matrix2d::Matrix2D;
|
use euclid::matrix2d::Matrix2D;
|
||||||
use euclid::point::Point2D;
|
use euclid::point::Point2D;
|
||||||
use euclid::rect::{Rect, TypedRect};
|
use euclid::rect::{Rect, TypedRect};
|
||||||
@ -27,10 +27,9 @@ use euclid::size::Size2D;
|
|||||||
use filters;
|
use filters;
|
||||||
use font_context::FontContext;
|
use font_context::FontContext;
|
||||||
use gfx_traits::{color, LayerKind};
|
use gfx_traits::{color, LayerKind};
|
||||||
use net_traits::image::base::{Image, PixelFormat};
|
use net_traits::image::base::PixelFormat;
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::{f32, mem, ptr};
|
use std::{f32, mem, ptr};
|
||||||
use style::computed_values::{border_style, filter, image_rendering, mix_blend_mode};
|
use style::computed_values::{border_style, filter, image_rendering, mix_blend_mode};
|
||||||
use text::TextRun;
|
use text::TextRun;
|
||||||
@ -181,21 +180,22 @@ impl<'a> PaintContext<'a> {
|
|||||||
pub fn draw_image(&self,
|
pub fn draw_image(&self,
|
||||||
bounds: &Rect<Au>,
|
bounds: &Rect<Au>,
|
||||||
stretch_size: &Size2D<Au>,
|
stretch_size: &Size2D<Au>,
|
||||||
image: Arc<Image>,
|
image_info: &WebRenderImageInfo,
|
||||||
|
image_data: &[u8],
|
||||||
image_rendering: image_rendering::T) {
|
image_rendering: image_rendering::T) {
|
||||||
let size = Size2D::new(image.width as i32, image.height as i32);
|
let size = Size2D::new(image_info.width as i32, image_info.height as i32);
|
||||||
let (pixel_width, source_format) = match image.format {
|
let (pixel_width, source_format) = match image_info.format {
|
||||||
PixelFormat::RGBA8 => (4, SurfaceFormat::B8G8R8A8),
|
PixelFormat::RGBA8 => (4, SurfaceFormat::B8G8R8A8),
|
||||||
PixelFormat::K8 => (1, SurfaceFormat::A8),
|
PixelFormat::K8 => (1, SurfaceFormat::A8),
|
||||||
PixelFormat::RGB8 => panic!("RGB8 color type not supported"),
|
PixelFormat::RGB8 => panic!("RGB8 color type not supported"),
|
||||||
PixelFormat::KA8 => panic!("KA8 color type not supported"),
|
PixelFormat::KA8 => panic!("KA8 color type not supported"),
|
||||||
};
|
};
|
||||||
let stride = image.width * pixel_width;
|
let stride = image_info.width * pixel_width;
|
||||||
let scale = self.screen_pixels_per_px();
|
let scale = self.screen_pixels_per_px();
|
||||||
|
|
||||||
self.draw_target.make_current();
|
self.draw_target.make_current();
|
||||||
let draw_target_ref = &self.draw_target;
|
let draw_target_ref = &self.draw_target;
|
||||||
let azure_surface = match draw_target_ref.create_source_surface_from_data(&image.bytes,
|
let azure_surface = match draw_target_ref.create_source_surface_from_data(image_data,
|
||||||
size,
|
size,
|
||||||
stride as i32,
|
stride as i32,
|
||||||
source_format) {
|
source_format) {
|
||||||
@ -204,7 +204,8 @@ impl<'a> PaintContext<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let source_rect = Rect::new(Point2D::new(0.0, 0.0),
|
let source_rect = Rect::new(Point2D::new(0.0, 0.0),
|
||||||
Size2D::new(image.width as AzFloat, image.height as AzFloat));
|
Size2D::new(image_info.width as AzFloat,
|
||||||
|
image_info.height as AzFloat));
|
||||||
let dest_rect = bounds.to_nearest_azure_rect(scale);
|
let dest_rect = bounds.to_nearest_azure_rect(scale);
|
||||||
|
|
||||||
// TODO(pcwalton): According to CSS-IMAGES-3 § 5.3, nearest-neighbor interpolation is a
|
// TODO(pcwalton): According to CSS-IMAGES-3 § 5.3, nearest-neighbor interpolation is a
|
||||||
|
@ -11,11 +11,12 @@ use app_units::Au;
|
|||||||
use canvas_traits::CanvasMsg;
|
use canvas_traits::CanvasMsg;
|
||||||
use euclid::Rect;
|
use euclid::Rect;
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
|
use gfx::display_list::WebRenderImageInfo;
|
||||||
use gfx::font_cache_thread::FontCacheThread;
|
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, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory};
|
||||||
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};
|
||||||
@ -24,7 +25,7 @@ use std::collections::HashMap;
|
|||||||
use std::hash::BuildHasherDefault;
|
use std::hash::BuildHasherDefault;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use style::context::{LocalStyleContext, StyleContext};
|
use style::context::{LocalStyleContext, StyleContext};
|
||||||
use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
|
use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
|
||||||
use style::selector_impl::ServoSelectorImpl;
|
use style::selector_impl::ServoSelectorImpl;
|
||||||
@ -99,6 +100,11 @@ pub struct SharedLayoutContext {
|
|||||||
|
|
||||||
/// The visible rects for each layer, as reported to us by the compositor.
|
/// The visible rects for each layer, as reported to us by the compositor.
|
||||||
pub visible_rects: Arc<HashMap<LayerId, Rect<Au>, BuildHasherDefault<FnvHasher>>>,
|
pub visible_rects: Arc<HashMap<LayerId, Rect<Au>, BuildHasherDefault<FnvHasher>>>,
|
||||||
|
|
||||||
|
/// A cache of WebRender image info.
|
||||||
|
pub webrender_image_cache: Arc<RwLock<HashMap<(Url, UsePlaceholder),
|
||||||
|
WebRenderImageInfo,
|
||||||
|
BuildHasherDefault<FnvHasher>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LayoutContext<'a> {
|
pub struct LayoutContext<'a> {
|
||||||
@ -132,45 +138,36 @@ impl<'a> LayoutContext<'a> {
|
|||||||
self.cached_local_layout_context.font_context.borrow_mut()
|
self.cached_local_layout_context.font_context.borrow_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_or_request_image(&self, url: Url, use_placeholder: UsePlaceholder)
|
fn get_or_request_image_synchronously(&self, url: Url, use_placeholder: UsePlaceholder)
|
||||||
-> Option<Arc<Image>> {
|
-> Option<Arc<Image>> {
|
||||||
|
debug_assert!(opts::get().output_file.is_some() || opts::get().exit_after_load);
|
||||||
|
|
||||||
// See if the image is already available
|
// See if the image is already available
|
||||||
let result = self.shared.image_cache_thread.find_image(url.clone(),
|
let result = self.shared.image_cache_thread.find_image(url.clone(), use_placeholder);
|
||||||
use_placeholder);
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(image) => Some(image),
|
Ok(image) => return Some(image),
|
||||||
Err(state) => {
|
Err(ImageState::LoadError) => {
|
||||||
// If we are emitting an output file, then we need to block on
|
// Image failed to load, so just return nothing
|
||||||
// image load or we risk emitting an output file missing the image.
|
return None
|
||||||
let is_sync = opts::get().output_file.is_some() ||
|
}
|
||||||
opts::get().exit_after_load;
|
Err(_) => {}
|
||||||
|
}
|
||||||
|
|
||||||
match (state, is_sync) {
|
// If we are emitting an output file, then we need to block on
|
||||||
// Image failed to load, so just return nothing
|
// image load or we risk emitting an output file missing the image.
|
||||||
(ImageState::LoadError, _) => None,
|
let (sync_tx, sync_rx) = ipc::channel().unwrap();
|
||||||
// Not loaded, test mode - load the image synchronously
|
self.shared.image_cache_thread.request_image(url, ImageCacheChan(sync_tx), None);
|
||||||
(_, true) => {
|
loop {
|
||||||
let (sync_tx, sync_rx) = ipc::channel().unwrap();
|
match sync_rx.recv() {
|
||||||
self.shared.image_cache_thread.request_image(url,
|
Err(_) => return None,
|
||||||
ImageCacheChan(sync_tx),
|
Ok(response) => {
|
||||||
None);
|
match response.image_response {
|
||||||
match sync_rx.recv().unwrap().image_response {
|
ImageResponse::Loaded(image) | ImageResponse::PlaceholderLoaded(image) => {
|
||||||
ImageResponse::Loaded(image) |
|
return Some(image)
|
||||||
ImageResponse::PlaceholderLoaded(image) => Some(image),
|
|
||||||
ImageResponse::None | ImageResponse::MetadataLoaded(_) => None,
|
|
||||||
}
|
}
|
||||||
|
ImageResponse::None | ImageResponse::MetadataLoaded(_) => {}
|
||||||
}
|
}
|
||||||
// Not yet requested, async mode - request image from the cache
|
|
||||||
(ImageState::NotRequested, false) => {
|
|
||||||
let sender = self.shared.image_cache_sender.lock().unwrap().clone();
|
|
||||||
self.shared.image_cache_thread.request_image(url, sender, None);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
// Image has been requested, is still pending. Return no image
|
|
||||||
// for this paint loop. When the image loads it will trigger
|
|
||||||
// a reflow and/or repaint.
|
|
||||||
(ImageState::Pending, false) => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,7 +177,7 @@ impl<'a> LayoutContext<'a> {
|
|||||||
-> Option<ImageOrMetadataAvailable> {
|
-> Option<ImageOrMetadataAvailable> {
|
||||||
// If we are emitting an output file, load the image synchronously.
|
// If we are emitting an output file, load the image synchronously.
|
||||||
if opts::get().output_file.is_some() || opts::get().exit_after_load {
|
if opts::get().output_file.is_some() || opts::get().exit_after_load {
|
||||||
return self.get_or_request_image(url, use_placeholder)
|
return self.get_or_request_image_synchronously(url, use_placeholder)
|
||||||
.map(|img| ImageOrMetadataAvailable::ImageAvailable(img));
|
.map(|img| ImageOrMetadataAvailable::ImageAvailable(img));
|
||||||
}
|
}
|
||||||
// See if the image is already available
|
// See if the image is already available
|
||||||
@ -202,4 +199,43 @@ impl<'a> LayoutContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_webrender_image_for_url(&self,
|
||||||
|
url: &Url,
|
||||||
|
use_placeholder: UsePlaceholder,
|
||||||
|
fetch_image_data_as_well: bool)
|
||||||
|
-> Option<(WebRenderImageInfo, Option<IpcSharedMemory>)> {
|
||||||
|
if !fetch_image_data_as_well {
|
||||||
|
let webrender_image_cache = self.shared.webrender_image_cache.read().unwrap();
|
||||||
|
if let Some(existing_webrender_image) =
|
||||||
|
webrender_image_cache.get(&((*url).clone(), use_placeholder)) {
|
||||||
|
return Some(((*existing_webrender_image).clone(), None))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.get_or_request_image_or_meta((*url).clone(), use_placeholder) {
|
||||||
|
Some(ImageOrMetadataAvailable::ImageAvailable(image)) => {
|
||||||
|
let image_info = WebRenderImageInfo::from_image(&*image);
|
||||||
|
if image_info.key.is_none() {
|
||||||
|
let bytes = if !fetch_image_data_as_well {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(image.bytes.clone())
|
||||||
|
};
|
||||||
|
Some((image_info, bytes))
|
||||||
|
} else if !fetch_image_data_as_well {
|
||||||
|
let mut webrender_image_cache = self.shared
|
||||||
|
.webrender_image_cache
|
||||||
|
.write()
|
||||||
|
.unwrap();
|
||||||
|
webrender_image_cache.insert(((*url).clone(), use_placeholder),
|
||||||
|
image_info);
|
||||||
|
Some((image_info, None))
|
||||||
|
} else {
|
||||||
|
Some((image_info, Some(image.bytes.clone())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None | Some(ImageOrMetadataAvailable::MetadataAvailable(_)) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ use gfx::display_list::{GradientDisplayItem};
|
|||||||
use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGLDisplayItem, LayeredItem, LayerInfo};
|
use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGLDisplayItem, LayeredItem, LayerInfo};
|
||||||
use gfx::display_list::{LineDisplayItem, OpaqueNode, SolidColorDisplayItem};
|
use gfx::display_list::{LineDisplayItem, OpaqueNode, SolidColorDisplayItem};
|
||||||
use gfx::display_list::{StackingContext, StackingContextId, StackingContextType};
|
use gfx::display_list::{StackingContext, StackingContextId, StackingContextType};
|
||||||
use gfx::display_list::{TextDisplayItem, TextOrientation, DisplayListEntry};
|
use gfx::display_list::{TextDisplayItem, TextOrientation, DisplayListEntry, WebRenderImageInfo};
|
||||||
use gfx::paint_thread::THREAD_TINT_COLORS;
|
use gfx::paint_thread::THREAD_TINT_COLORS;
|
||||||
use gfx::text::glyph::CharIndex;
|
use gfx::text::glyph::CharIndex;
|
||||||
use gfx_traits::{color, ScrollPolicy};
|
use gfx_traits::{color, ScrollPolicy};
|
||||||
@ -37,7 +37,7 @@ use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
|
|||||||
use ipc_channel::ipc::{self, IpcSharedMemory};
|
use ipc_channel::ipc::{self, IpcSharedMemory};
|
||||||
use list_item::ListItemFlow;
|
use list_item::ListItemFlow;
|
||||||
use model::{self, MaybeAuto, ToGfxMatrix};
|
use model::{self, MaybeAuto, ToGfxMatrix};
|
||||||
use net_traits::image::base::{Image, PixelFormat};
|
use net_traits::image::base::PixelFormat;
|
||||||
use net_traits::image_cache_thread::UsePlaceholder;
|
use net_traits::image_cache_thread::UsePlaceholder;
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
@ -136,7 +136,7 @@ pub trait FragmentDisplayListBuilding {
|
|||||||
fn compute_background_image_size(&self,
|
fn compute_background_image_size(&self,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
bounds: &Rect<Au>,
|
bounds: &Rect<Au>,
|
||||||
image: &Image)
|
image: &WebRenderImageInfo)
|
||||||
-> Size2D<Au>;
|
-> Size2D<Au>;
|
||||||
|
|
||||||
/// Adds the display items necessary to paint the background image of this fragment to the
|
/// Adds the display items necessary to paint the background image of this fragment to the
|
||||||
@ -404,7 +404,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||||||
fn compute_background_image_size(&self,
|
fn compute_background_image_size(&self,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
bounds: &Rect<Au>,
|
bounds: &Rect<Au>,
|
||||||
image: &Image)
|
image: &WebRenderImageInfo)
|
||||||
-> Size2D<Au> {
|
-> Size2D<Au> {
|
||||||
// If `image_aspect_ratio` < `bounds_aspect_ratio`, the image is tall; otherwise, it is
|
// If `image_aspect_ratio` < `bounds_aspect_ratio`, the image is tall; otherwise, it is
|
||||||
// wide.
|
// wide.
|
||||||
@ -462,14 +462,17 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||||||
clip: &ClippingRegion,
|
clip: &ClippingRegion,
|
||||||
image_url: &Url) {
|
image_url: &Url) {
|
||||||
let background = style.get_background();
|
let background = style.get_background();
|
||||||
let image =
|
let fetch_image_data_as_well = !opts::get().use_webrender;
|
||||||
state.layout_context.get_or_request_image(image_url.clone(), UsePlaceholder::No);
|
let webrender_image =
|
||||||
if let Some(image) = image {
|
state.layout_context.get_webrender_image_for_url(image_url,
|
||||||
|
UsePlaceholder::No,
|
||||||
|
fetch_image_data_as_well);
|
||||||
|
if let Some((webrender_image, image_data)) = 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.
|
||||||
let mut bounds = *absolute_bounds;
|
let mut bounds = *absolute_bounds;
|
||||||
let image_size = self.compute_background_image_size(style, &bounds, &*image);
|
let image_size = self.compute_background_image_size(style, &bounds, &webrender_image);
|
||||||
|
|
||||||
// Clip.
|
// Clip.
|
||||||
//
|
//
|
||||||
@ -560,7 +563,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||||||
style,
|
style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
&clip),
|
&clip),
|
||||||
image: image.clone(),
|
webrender_image: webrender_image,
|
||||||
|
image_data: image_data.map(Arc::new),
|
||||||
stretch_size: Size2D::new(image_size.width, image_size.height),
|
stretch_size: Size2D::new(image_size.width, image_size.height),
|
||||||
image_rendering: style.get_effects().image_rendering.clone(),
|
image_rendering: style.get_effects().image_rendering.clone(),
|
||||||
}), display_list_section);
|
}), display_list_section);
|
||||||
@ -1173,7 +1177,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||||||
&*self.style,
|
&*self.style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
clip),
|
clip),
|
||||||
image: image.clone(),
|
webrender_image: WebRenderImageInfo::from_image(image),
|
||||||
|
image_data: Some(Arc::new(image.bytes.clone())),
|
||||||
stretch_size: stacking_relative_content_box.size,
|
stretch_size: stacking_relative_content_box.size,
|
||||||
image_rendering: self.style.get_effects().image_rendering.clone(),
|
image_rendering: self.style.get_effects().image_rendering.clone(),
|
||||||
}), DisplayListSection::Content);
|
}), DisplayListSection::Content);
|
||||||
@ -1214,13 +1219,13 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||||||
&*self.style,
|
&*self.style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
clip),
|
clip),
|
||||||
image: Arc::new(Image {
|
image_data: Some(Arc::new(canvas_data.image_data)),
|
||||||
|
webrender_image: WebRenderImageInfo {
|
||||||
width: width as u32,
|
width: width as u32,
|
||||||
height: height as u32,
|
height: height as u32,
|
||||||
format: PixelFormat::RGBA8,
|
format: PixelFormat::RGBA8,
|
||||||
bytes: canvas_data.image_data,
|
key: canvas_data.image_key,
|
||||||
id: canvas_data.image_key,
|
},
|
||||||
}),
|
|
||||||
stretch_size: stacking_relative_content_box.size,
|
stretch_size: stacking_relative_content_box.size,
|
||||||
image_rendering: image_rendering::T::Auto,
|
image_rendering: image_rendering::T::Auto,
|
||||||
})
|
})
|
||||||
|
@ -24,6 +24,7 @@ use flow_ref::{self, FlowRef};
|
|||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
use gfx::display_list::{ClippingRegion, DisplayItemMetadata, DisplayList, LayerInfo};
|
use gfx::display_list::{ClippingRegion, DisplayItemMetadata, DisplayList, LayerInfo};
|
||||||
use gfx::display_list::{OpaqueNode, StackingContext, StackingContextId, StackingContextType};
|
use gfx::display_list::{OpaqueNode, StackingContext, StackingContextId, StackingContextType};
|
||||||
|
use gfx::display_list::{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;
|
||||||
@ -39,6 +40,7 @@ use layout_traits::LayoutThreadFactory;
|
|||||||
use log;
|
use log;
|
||||||
use msg::constellation_msg::{ConstellationChan, ConvertPipelineIdToWebRender, Failure, PipelineId};
|
use msg::constellation_msg::{ConstellationChan, ConvertPipelineIdToWebRender, Failure, PipelineId};
|
||||||
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
|
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
|
||||||
|
use net_traits::image_cache_thread::{UsePlaceholder};
|
||||||
use parallel;
|
use parallel;
|
||||||
use profile_traits::mem::{self, Report, ReportKind, ReportsChan};
|
use profile_traits::mem::{self, Report, ReportKind, ReportsChan};
|
||||||
use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType};
|
use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType};
|
||||||
@ -83,8 +85,8 @@ use util::opts;
|
|||||||
use util::thread;
|
use util::thread;
|
||||||
use util::thread_state;
|
use util::thread_state;
|
||||||
use util::workqueue::WorkQueue;
|
use util::workqueue::WorkQueue;
|
||||||
use webrender_helpers::WebRenderDisplayListConverter;
|
use webrender_helpers::{WebRenderDisplayListConverter, WebRenderFrameBuilder};
|
||||||
use webrender_traits::{self, AuxiliaryListsBuilder};
|
use webrender_traits;
|
||||||
use wrapper::{LayoutNode, NonOpaqueStyleAndLayoutData, ServoLayoutNode, ThreadSafeLayoutNode};
|
use wrapper::{LayoutNode, NonOpaqueStyleAndLayoutData, ServoLayoutNode, ThreadSafeLayoutNode};
|
||||||
|
|
||||||
/// The number of screens of data we're allowed to generate display lists for in each direction.
|
/// The number of screens of data we're allowed to generate display lists for in each direction.
|
||||||
@ -235,6 +237,10 @@ pub struct LayoutThread {
|
|||||||
/// The CSS error reporter for all CSS loaded in this layout thread
|
/// The CSS error reporter for all CSS loaded in this layout thread
|
||||||
error_reporter: CSSErrorReporter,
|
error_reporter: CSSErrorReporter,
|
||||||
|
|
||||||
|
webrender_image_cache: Arc<RwLock<HashMap<(Url, UsePlaceholder),
|
||||||
|
WebRenderImageInfo,
|
||||||
|
BuildHasherDefault<FnvHasher>>>>,
|
||||||
|
|
||||||
// Webrender interface, if enabled.
|
// Webrender interface, if enabled.
|
||||||
webrender_api: Option<webrender_traits::RenderApi>,
|
webrender_api: Option<webrender_traits::RenderApi>,
|
||||||
}
|
}
|
||||||
@ -475,6 +481,8 @@ impl LayoutThread {
|
|||||||
pipelineid: id,
|
pipelineid: id,
|
||||||
script_chan: Arc::new(Mutex::new(script_chan)),
|
script_chan: Arc::new(Mutex::new(script_chan)),
|
||||||
},
|
},
|
||||||
|
webrender_image_cache:
|
||||||
|
Arc::new(RwLock::new(HashMap::with_hasher(Default::default()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,6 +524,7 @@ impl LayoutThread {
|
|||||||
canvas_layers_sender: Mutex::new(self.canvas_layers_sender.clone()),
|
canvas_layers_sender: Mutex::new(self.canvas_layers_sender.clone()),
|
||||||
url: (*url).clone(),
|
url: (*url).clone(),
|
||||||
visible_rects: self.visible_rects.clone(),
|
visible_rects: self.visible_rects.clone(),
|
||||||
|
webrender_image_cache: self.webrender_image_cache.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,7 +949,6 @@ impl LayoutThread {
|
|||||||
self.epoch.next();
|
self.epoch.next();
|
||||||
|
|
||||||
if opts::get().use_webrender {
|
if opts::get().use_webrender {
|
||||||
let api = self.webrender_api.as_ref().unwrap();
|
|
||||||
// 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);
|
||||||
@ -948,13 +956,13 @@ impl LayoutThread {
|
|||||||
|
|
||||||
// TODO(gw) For now only create a root scrolling layer!
|
// TODO(gw) For now only create a root scrolling layer!
|
||||||
let root_scroll_layer_id = webrender_traits::ScrollLayerId::new(pipeline_id, 0);
|
let root_scroll_layer_id = webrender_traits::ScrollLayerId::new(pipeline_id, 0);
|
||||||
let mut auxiliary_lists_builder = AuxiliaryListsBuilder::new();
|
let mut frame_builder = WebRenderFrameBuilder::new(pipeline_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(
|
||||||
&self.webrender_api.as_ref().unwrap(),
|
&mut self.webrender_api.as_mut().unwrap(),
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
epoch,
|
epoch,
|
||||||
Some(root_scroll_layer_id),
|
Some(root_scroll_layer_id),
|
||||||
&mut auxiliary_lists_builder);
|
&mut frame_builder);
|
||||||
let root_background_color = get_root_flow_background_color(
|
let root_background_color = get_root_flow_background_color(
|
||||||
flow_ref::deref_mut(layout_root));
|
flow_ref::deref_mut(layout_root));
|
||||||
let root_background_color =
|
let root_background_color =
|
||||||
@ -966,12 +974,16 @@ impl LayoutThread {
|
|||||||
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());
|
||||||
|
|
||||||
|
let api = self.webrender_api.as_ref().unwrap();
|
||||||
api.set_root_stacking_context(sc_id,
|
api.set_root_stacking_context(sc_id,
|
||||||
root_background_color,
|
root_background_color,
|
||||||
epoch,
|
epoch,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
viewport_size,
|
viewport_size,
|
||||||
auxiliary_lists_builder.finalize());
|
frame_builder.stacking_contexts,
|
||||||
|
frame_builder.display_lists,
|
||||||
|
frame_builder.auxiliary_lists_builder
|
||||||
|
.finalize());
|
||||||
} else {
|
} else {
|
||||||
self.paint_chan
|
self.paint_chan
|
||||||
.send(LayoutToPaintMsg::PaintInit(self.epoch, display_list))
|
.send(LayoutToPaintMsg::PaintInit(self.epoch, display_list))
|
||||||
|
@ -19,26 +19,26 @@ use msg::constellation_msg::ConvertPipelineIdToWebRender;
|
|||||||
use style::computed_values::filter::{self, Filter};
|
use style::computed_values::filter::{self, Filter};
|
||||||
use style::computed_values::{image_rendering, mix_blend_mode};
|
use style::computed_values::{image_rendering, mix_blend_mode};
|
||||||
use style::values::computed::BorderStyle;
|
use style::values::computed::BorderStyle;
|
||||||
use webrender_traits::{self, AuxiliaryListsBuilder};
|
use webrender_traits::{self, AuxiliaryListsBuilder, DisplayListId, PipelineId, StackingContextId};
|
||||||
|
|
||||||
trait WebRenderStackingContextConverter {
|
trait WebRenderStackingContextConverter {
|
||||||
fn convert_to_webrender<'a>(&self,
|
fn convert_to_webrender<'a>(&self,
|
||||||
traversal: &mut DisplayListTraversal<'a>,
|
traversal: &mut DisplayListTraversal<'a>,
|
||||||
api: &webrender_traits::RenderApi,
|
api: &mut webrender_traits::RenderApi,
|
||||||
pipeline_id: webrender_traits::PipelineId,
|
pipeline_id: webrender_traits::PipelineId,
|
||||||
epoch: webrender_traits::Epoch,
|
epoch: webrender_traits::Epoch,
|
||||||
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
||||||
auxiliary_lists_builder: &mut AuxiliaryListsBuilder)
|
frame_builder: &mut WebRenderFrameBuilder)
|
||||||
-> webrender_traits::StackingContextId;
|
-> webrender_traits::StackingContextId;
|
||||||
|
|
||||||
fn convert_children_to_webrender<'a>(&self,
|
fn convert_children_to_webrender<'a>(&self,
|
||||||
traversal: &mut DisplayListTraversal<'a>,
|
traversal: &mut DisplayListTraversal<'a>,
|
||||||
api: &webrender_traits::RenderApi,
|
api: &mut webrender_traits::RenderApi,
|
||||||
pipeline_id: webrender_traits::PipelineId,
|
pipeline_id: webrender_traits::PipelineId,
|
||||||
epoch: webrender_traits::Epoch,
|
epoch: webrender_traits::Epoch,
|
||||||
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
||||||
builder: &mut webrender_traits::DisplayListBuilder,
|
builder: &mut webrender_traits::DisplayListBuilder,
|
||||||
auxiliary_lists_builder: &mut AuxiliaryListsBuilder,
|
frame_builder: &mut WebRenderFrameBuilder,
|
||||||
force_positioned_stacking_level: bool);
|
force_positioned_stacking_level: bool);
|
||||||
|
|
||||||
fn web_render_stacking_level(&self) -> webrender_traits::StackingLevel;
|
fn web_render_stacking_level(&self) -> webrender_traits::StackingLevel;
|
||||||
@ -46,11 +46,11 @@ trait WebRenderStackingContextConverter {
|
|||||||
|
|
||||||
pub trait WebRenderDisplayListConverter {
|
pub trait WebRenderDisplayListConverter {
|
||||||
fn convert_to_webrender(&self,
|
fn convert_to_webrender(&self,
|
||||||
api: &webrender_traits::RenderApi,
|
api: &mut webrender_traits::RenderApi,
|
||||||
pipeline_id: webrender_traits::PipelineId,
|
pipeline_id: webrender_traits::PipelineId,
|
||||||
epoch: webrender_traits::Epoch,
|
epoch: webrender_traits::Epoch,
|
||||||
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
||||||
auxiliary_lists_builder: &mut AuxiliaryListsBuilder)
|
frame_builder: &mut WebRenderFrameBuilder)
|
||||||
-> webrender_traits::StackingContextId;
|
-> webrender_traits::StackingContextId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ trait WebRenderDisplayItemConverter {
|
|||||||
fn convert_to_webrender(&self,
|
fn convert_to_webrender(&self,
|
||||||
level: webrender_traits::StackingLevel,
|
level: webrender_traits::StackingLevel,
|
||||||
builder: &mut webrender_traits::DisplayListBuilder,
|
builder: &mut webrender_traits::DisplayListBuilder,
|
||||||
auxiliary_lists_builder: &mut AuxiliaryListsBuilder);
|
frame_builder: &mut WebRenderFrameBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
trait WebRenderDisplayListEntryConverter {
|
trait WebRenderDisplayListEntryConverter {
|
||||||
@ -171,12 +171,12 @@ impl ToGradientStop for GradientStop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trait ToClipRegion {
|
trait ToClipRegion {
|
||||||
fn to_clip_region(&self, auxiliary_lists_builder: &mut AuxiliaryListsBuilder)
|
fn to_clip_region(&self, frame_builder: &mut WebRenderFrameBuilder)
|
||||||
-> webrender_traits::ClipRegion;
|
-> webrender_traits::ClipRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToClipRegion for ClippingRegion {
|
impl ToClipRegion for ClippingRegion {
|
||||||
fn to_clip_region(&self, auxiliary_lists_builder: &mut AuxiliaryListsBuilder)
|
fn to_clip_region(&self, frame_builder: &mut WebRenderFrameBuilder)
|
||||||
-> webrender_traits::ClipRegion {
|
-> webrender_traits::ClipRegion {
|
||||||
webrender_traits::ClipRegion::new(&self.main.to_rectf(),
|
webrender_traits::ClipRegion::new(&self.main.to_rectf(),
|
||||||
self.complex.iter().map(|complex_clipping_region| {
|
self.complex.iter().map(|complex_clipping_region| {
|
||||||
@ -185,7 +185,7 @@ impl ToClipRegion for ClippingRegion {
|
|||||||
complex_clipping_region.radii.to_border_radius(),
|
complex_clipping_region.radii.to_border_radius(),
|
||||||
)
|
)
|
||||||
}).collect(),
|
}).collect(),
|
||||||
auxiliary_lists_builder)
|
&mut frame_builder.auxiliary_lists_builder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,12 +272,12 @@ impl ToFilterOps for filter::T {
|
|||||||
impl WebRenderStackingContextConverter for StackingContext {
|
impl WebRenderStackingContextConverter for StackingContext {
|
||||||
fn convert_children_to_webrender<'a>(&self,
|
fn convert_children_to_webrender<'a>(&self,
|
||||||
traversal: &mut DisplayListTraversal<'a>,
|
traversal: &mut DisplayListTraversal<'a>,
|
||||||
api: &webrender_traits::RenderApi,
|
api: &mut webrender_traits::RenderApi,
|
||||||
pipeline_id: webrender_traits::PipelineId,
|
pipeline_id: webrender_traits::PipelineId,
|
||||||
epoch: webrender_traits::Epoch,
|
epoch: webrender_traits::Epoch,
|
||||||
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
||||||
builder: &mut webrender_traits::DisplayListBuilder,
|
builder: &mut webrender_traits::DisplayListBuilder,
|
||||||
auxiliary_lists_builder: &mut AuxiliaryListsBuilder,
|
frame_builder: &mut WebRenderFrameBuilder,
|
||||||
force_positioned_stacking_level: bool) {
|
force_positioned_stacking_level: bool) {
|
||||||
for child in self.children.iter() {
|
for child in self.children.iter() {
|
||||||
while let Some(item) = traversal.advance(self) {
|
while let Some(item) = traversal.advance(self) {
|
||||||
@ -286,7 +286,7 @@ impl WebRenderStackingContextConverter for StackingContext {
|
|||||||
} else {
|
} else {
|
||||||
item.web_render_stacking_level()
|
item.web_render_stacking_level()
|
||||||
};
|
};
|
||||||
item.item.convert_to_webrender(stacking_level, builder, auxiliary_lists_builder);
|
item.item.convert_to_webrender(stacking_level, builder, frame_builder);
|
||||||
|
|
||||||
}
|
}
|
||||||
if child.context_type == StackingContextType::Real {
|
if child.context_type == StackingContextType::Real {
|
||||||
@ -295,7 +295,7 @@ impl WebRenderStackingContextConverter for StackingContext {
|
|||||||
pipeline_id,
|
pipeline_id,
|
||||||
epoch,
|
epoch,
|
||||||
None,
|
None,
|
||||||
auxiliary_lists_builder);
|
frame_builder);
|
||||||
builder.push_stacking_context(child.web_render_stacking_level(),
|
builder.push_stacking_context(child.web_render_stacking_level(),
|
||||||
stacking_context_id);
|
stacking_context_id);
|
||||||
} else {
|
} else {
|
||||||
@ -305,7 +305,7 @@ impl WebRenderStackingContextConverter for StackingContext {
|
|||||||
epoch,
|
epoch,
|
||||||
scroll_layer_id,
|
scroll_layer_id,
|
||||||
builder,
|
builder,
|
||||||
auxiliary_lists_builder,
|
frame_builder,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,17 +313,17 @@ impl WebRenderStackingContextConverter for StackingContext {
|
|||||||
while let Some(item) = traversal.advance(self) {
|
while let Some(item) = traversal.advance(self) {
|
||||||
item.item.convert_to_webrender(webrender_traits::StackingLevel::PositionedContent,
|
item.item.convert_to_webrender(webrender_traits::StackingLevel::PositionedContent,
|
||||||
builder,
|
builder,
|
||||||
auxiliary_lists_builder);
|
frame_builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_to_webrender<'a>(&self,
|
fn convert_to_webrender<'a>(&self,
|
||||||
traversal: &mut DisplayListTraversal<'a>,
|
traversal: &mut DisplayListTraversal<'a>,
|
||||||
api: &webrender_traits::RenderApi,
|
api: &mut webrender_traits::RenderApi,
|
||||||
pipeline_id: webrender_traits::PipelineId,
|
pipeline_id: webrender_traits::PipelineId,
|
||||||
epoch: webrender_traits::Epoch,
|
epoch: webrender_traits::Epoch,
|
||||||
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
||||||
auxiliary_lists_builder: &mut AuxiliaryListsBuilder)
|
frame_builder: &mut WebRenderFrameBuilder)
|
||||||
-> webrender_traits::StackingContextId {
|
-> webrender_traits::StackingContextId {
|
||||||
let scroll_policy = self.layer_info
|
let scroll_policy = self.layer_info
|
||||||
.map_or(webrender_traits::ScrollPolicy::Scrollable, |info| {
|
.map_or(webrender_traits::ScrollPolicy::Scrollable, |info| {
|
||||||
@ -333,17 +333,18 @@ impl WebRenderStackingContextConverter for StackingContext {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut sc = webrender_traits::StackingContext::new(scroll_layer_id,
|
let mut sc =
|
||||||
scroll_policy,
|
webrender_traits::StackingContext::new(scroll_layer_id,
|
||||||
self.bounds.to_rectf(),
|
scroll_policy,
|
||||||
self.overflow.to_rectf(),
|
self.bounds.to_rectf(),
|
||||||
self.z_index,
|
self.overflow.to_rectf(),
|
||||||
&self.transform,
|
self.z_index,
|
||||||
&self.perspective,
|
&self.transform,
|
||||||
self.establishes_3d_context,
|
&self.perspective,
|
||||||
self.blend_mode.to_blend_mode(),
|
self.establishes_3d_context,
|
||||||
self.filters.to_filter_ops(),
|
self.blend_mode.to_blend_mode(),
|
||||||
auxiliary_lists_builder);
|
self.filters.to_filter_ops(),
|
||||||
|
&mut frame_builder.auxiliary_lists_builder);
|
||||||
let mut builder = webrender_traits::DisplayListBuilder::new();
|
let mut builder = webrender_traits::DisplayListBuilder::new();
|
||||||
self.convert_children_to_webrender(traversal,
|
self.convert_children_to_webrender(traversal,
|
||||||
api,
|
api,
|
||||||
@ -351,10 +352,10 @@ impl WebRenderStackingContextConverter for StackingContext {
|
|||||||
epoch,
|
epoch,
|
||||||
scroll_layer_id,
|
scroll_layer_id,
|
||||||
&mut builder,
|
&mut builder,
|
||||||
auxiliary_lists_builder,
|
frame_builder,
|
||||||
false);
|
false);
|
||||||
api.add_display_list(builder.finalize(), &mut sc, pipeline_id, epoch);
|
frame_builder.add_display_list(api, builder.finalize(), &mut sc);
|
||||||
api.add_stacking_context(sc, pipeline_id, epoch)
|
frame_builder.add_stacking_context(api, pipeline_id, sc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn web_render_stacking_level(&self) -> webrender_traits::StackingLevel {
|
fn web_render_stacking_level(&self) -> webrender_traits::StackingLevel {
|
||||||
@ -368,11 +369,11 @@ impl WebRenderStackingContextConverter for StackingContext {
|
|||||||
|
|
||||||
impl WebRenderDisplayListConverter for DisplayList {
|
impl WebRenderDisplayListConverter for DisplayList {
|
||||||
fn convert_to_webrender(&self,
|
fn convert_to_webrender(&self,
|
||||||
api: &webrender_traits::RenderApi,
|
api: &mut webrender_traits::RenderApi,
|
||||||
pipeline_id: webrender_traits::PipelineId,
|
pipeline_id: webrender_traits::PipelineId,
|
||||||
epoch: webrender_traits::Epoch,
|
epoch: webrender_traits::Epoch,
|
||||||
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
|
||||||
auxiliary_lists_builder: &mut AuxiliaryListsBuilder)
|
frame_builder: &mut WebRenderFrameBuilder)
|
||||||
-> webrender_traits::StackingContextId {
|
-> webrender_traits::StackingContextId {
|
||||||
let mut traversal = DisplayListTraversal {
|
let mut traversal = DisplayListTraversal {
|
||||||
display_list: self,
|
display_list: self,
|
||||||
@ -385,7 +386,7 @@ impl WebRenderDisplayListConverter for DisplayList {
|
|||||||
pipeline_id,
|
pipeline_id,
|
||||||
epoch,
|
epoch,
|
||||||
scroll_layer_id,
|
scroll_layer_id,
|
||||||
auxiliary_lists_builder)
|
frame_builder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,14 +394,14 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||||||
fn convert_to_webrender(&self,
|
fn convert_to_webrender(&self,
|
||||||
level: webrender_traits::StackingLevel,
|
level: webrender_traits::StackingLevel,
|
||||||
builder: &mut webrender_traits::DisplayListBuilder,
|
builder: &mut webrender_traits::DisplayListBuilder,
|
||||||
auxiliary_lists_builder: &mut AuxiliaryListsBuilder) {
|
frame_builder: &mut WebRenderFrameBuilder) {
|
||||||
match *self {
|
match *self {
|
||||||
DisplayItem::SolidColorClass(ref item) => {
|
DisplayItem::SolidColorClass(ref item) => {
|
||||||
let color = item.color.to_colorf();
|
let color = item.color.to_colorf();
|
||||||
if color.a > 0.0 {
|
if color.a > 0.0 {
|
||||||
builder.push_rect(level,
|
builder.push_rect(level,
|
||||||
item.base.bounds.to_rectf(),
|
item.base.bounds.to_rectf(),
|
||||||
item.base.clip.to_clip_region(auxiliary_lists_builder),
|
item.base.clip.to_clip_region(frame_builder),
|
||||||
color);
|
color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,22 +426,22 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||||||
if glyphs.len() > 0 {
|
if glyphs.len() > 0 {
|
||||||
builder.push_text(level,
|
builder.push_text(level,
|
||||||
item.base.bounds.to_rectf(),
|
item.base.bounds.to_rectf(),
|
||||||
item.base.clip.to_clip_region(auxiliary_lists_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.expect("Font not added to webrender!"),
|
||||||
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,
|
||||||
auxiliary_lists_builder);
|
&mut frame_builder.auxiliary_lists_builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DisplayItem::ImageClass(ref item) => {
|
DisplayItem::ImageClass(ref item) => {
|
||||||
if let Some(id) = item.image.id {
|
if let Some(id) = item.webrender_image.key {
|
||||||
if item.stretch_size.width > Au(0) &&
|
if item.stretch_size.width > Au(0) &&
|
||||||
item.stretch_size.height > Au(0) {
|
item.stretch_size.height > Au(0) {
|
||||||
builder.push_image(level,
|
builder.push_image(level,
|
||||||
item.base.bounds.to_rectf(),
|
item.base.bounds.to_rectf(),
|
||||||
item.base.clip.to_clip_region(auxiliary_lists_builder),
|
item.base.clip.to_clip_region(frame_builder),
|
||||||
item.stretch_size.to_sizef(),
|
item.stretch_size.to_sizef(),
|
||||||
item.image_rendering.to_image_rendering(),
|
item.image_rendering.to_image_rendering(),
|
||||||
id);
|
id);
|
||||||
@ -450,7 +451,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||||||
DisplayItem::WebGLClass(ref item) => {
|
DisplayItem::WebGLClass(ref item) => {
|
||||||
builder.push_webgl_canvas(level,
|
builder.push_webgl_canvas(level,
|
||||||
item.base.bounds.to_rectf(),
|
item.base.bounds.to_rectf(),
|
||||||
item.base.clip.to_clip_region(auxiliary_lists_builder),
|
item.base.clip.to_clip_region(frame_builder),
|
||||||
item.context_id);
|
item.context_id);
|
||||||
}
|
}
|
||||||
DisplayItem::BorderClass(ref item) => {
|
DisplayItem::BorderClass(ref item) => {
|
||||||
@ -478,7 +479,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||||||
let radius = item.radius.to_border_radius();
|
let radius = item.radius.to_border_radius();
|
||||||
builder.push_border(level,
|
builder.push_border(level,
|
||||||
rect,
|
rect,
|
||||||
item.base.clip.to_clip_region(auxiliary_lists_builder),
|
item.base.clip.to_clip_region(frame_builder),
|
||||||
left,
|
left,
|
||||||
top,
|
top,
|
||||||
right,
|
right,
|
||||||
@ -495,11 +496,11 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||||||
}
|
}
|
||||||
builder.push_gradient(level,
|
builder.push_gradient(level,
|
||||||
rect,
|
rect,
|
||||||
item.base.clip.to_clip_region(auxiliary_lists_builder),
|
item.base.clip.to_clip_region(frame_builder),
|
||||||
start_point,
|
start_point,
|
||||||
end_point,
|
end_point,
|
||||||
stops,
|
stops,
|
||||||
auxiliary_lists_builder);
|
&mut frame_builder.auxiliary_lists_builder);
|
||||||
}
|
}
|
||||||
DisplayItem::LineClass(..) => {
|
DisplayItem::LineClass(..) => {
|
||||||
println!("TODO DisplayItem::LineClass");
|
println!("TODO DisplayItem::LineClass");
|
||||||
@ -512,7 +513,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||||||
let box_bounds = item.box_bounds.to_rectf();
|
let box_bounds = item.box_bounds.to_rectf();
|
||||||
builder.push_box_shadow(level,
|
builder.push_box_shadow(level,
|
||||||
rect,
|
rect,
|
||||||
item.base.clip.to_clip_region(auxiliary_lists_builder),
|
item.base.clip.to_clip_region(frame_builder),
|
||||||
box_bounds,
|
box_bounds,
|
||||||
item.offset.to_pointf(),
|
item.offset.to_pointf(),
|
||||||
item.color.to_colorf(),
|
item.color.to_colorf(),
|
||||||
@ -526,9 +527,52 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||||||
let pipeline_id = item.iframe.to_webrender();
|
let pipeline_id = item.iframe.to_webrender();
|
||||||
builder.push_iframe(level,
|
builder.push_iframe(level,
|
||||||
rect,
|
rect,
|
||||||
item.base.clip.to_clip_region(auxiliary_lists_builder),
|
item.base.clip.to_clip_region(frame_builder),
|
||||||
pipeline_id);
|
pipeline_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct WebRenderFrameBuilder {
|
||||||
|
pub stacking_contexts: Vec<(StackingContextId, webrender_traits::StackingContext)>,
|
||||||
|
pub display_lists: Vec<(DisplayListId, webrender_traits::BuiltDisplayList)>,
|
||||||
|
pub auxiliary_lists_builder: AuxiliaryListsBuilder,
|
||||||
|
pub root_pipeline_id: PipelineId
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebRenderFrameBuilder {
|
||||||
|
pub fn new(root_pipeline_id: PipelineId) -> WebRenderFrameBuilder {
|
||||||
|
WebRenderFrameBuilder {
|
||||||
|
stacking_contexts: vec![],
|
||||||
|
display_lists: vec![],
|
||||||
|
auxiliary_lists_builder: AuxiliaryListsBuilder::new(),
|
||||||
|
root_pipeline_id: root_pipeline_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_stacking_context(&mut self,
|
||||||
|
api: &mut webrender_traits::RenderApi,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
stacking_context: webrender_traits::StackingContext)
|
||||||
|
-> StackingContextId {
|
||||||
|
assert!(pipeline_id == self.root_pipeline_id);
|
||||||
|
let id = api.next_stacking_context_id();
|
||||||
|
self.stacking_contexts.push((id, stacking_context));
|
||||||
|
id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_display_list(&mut self,
|
||||||
|
api: &mut webrender_traits::RenderApi,
|
||||||
|
display_list: webrender_traits::BuiltDisplayList,
|
||||||
|
stacking_context: &mut webrender_traits::StackingContext)
|
||||||
|
-> DisplayListId {
|
||||||
|
let id = api.next_display_list_id();
|
||||||
|
stacking_context.has_stacking_contexts = stacking_context.has_stacking_contexts ||
|
||||||
|
display_list.descriptor().has_stacking_contexts;
|
||||||
|
stacking_context.display_lists.push(id);
|
||||||
|
self.display_lists.push((id, display_list));
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ pub struct ImageMetadata {
|
|||||||
pub height: u32,
|
pub height: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, HeapSizeOf)]
|
#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
|
@ -96,7 +96,7 @@ pub enum ImageCacheCommand {
|
|||||||
Exit(IpcSender<()>),
|
Exit(IpcSender<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Deserialize, Serialize)]
|
#[derive(Copy, Clone, PartialEq, Hash, Eq, Deserialize, Serialize)]
|
||||||
pub enum UsePlaceholder {
|
pub enum UsePlaceholder {
|
||||||
No,
|
No,
|
||||||
Yes,
|
Yes,
|
||||||
|
4
servo/components/servo/Cargo.lock
generated
4
servo/components/servo/Cargo.lock
generated
@ -2306,7 +2306,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "webrender"
|
name = "webrender"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/webrender#ab1c795612a5bd560a8adf750b4630cf1d24f706"
|
source = "git+https://github.com/servo/webrender#2a71ccb0249601b25ef156f9a585a001c8d606cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2328,7 +2328,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "webrender_traits"
|
name = "webrender_traits"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/webrender_traits#0bff8081020c0fc0a31258482f4c6e9bfaf597f2"
|
source = "git+https://github.com/servo/webrender_traits#2ad5e68f3f49c91ef627848d9561649f3c1be344"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
4
servo/ports/cef/Cargo.lock
generated
4
servo/ports/cef/Cargo.lock
generated
@ -2182,7 +2182,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "webrender"
|
name = "webrender"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/webrender#ab1c795612a5bd560a8adf750b4630cf1d24f706"
|
source = "git+https://github.com/servo/webrender#2a71ccb0249601b25ef156f9a585a001c8d606cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2204,7 +2204,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "webrender_traits"
|
name = "webrender_traits"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/webrender_traits#0bff8081020c0fc0a31258482f4c6e9bfaf597f2"
|
source = "git+https://github.com/servo/webrender_traits#2ad5e68f3f49c91ef627848d9561649f3c1be344"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
4
servo/ports/gonk/Cargo.lock
generated
4
servo/ports/gonk/Cargo.lock
generated
@ -2131,7 +2131,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "webrender"
|
name = "webrender"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/webrender#ab1c795612a5bd560a8adf750b4630cf1d24f706"
|
source = "git+https://github.com/servo/webrender#2a71ccb0249601b25ef156f9a585a001c8d606cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2153,7 +2153,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "webrender_traits"
|
name = "webrender_traits"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/webrender_traits#0bff8081020c0fc0a31258482f4c6e9bfaf597f2"
|
source = "git+https://github.com/servo/webrender_traits#2ad5e68f3f49c91ef627848d9561649f3c1be344"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
Loading…
Reference in New Issue
Block a user