Bug 1434288 - Update webrender to commit e772c3cb8ea0a35e6477e9dc8dd2144e2de87b56. r=jrmuizel

MozReview-Commit-ID: 4VM5EAtkjNt

--HG--
extra : rebase_source : 5c1b5da5a99fe9405f9810030b8e3422ac82e519
This commit is contained in:
Kartikaya Gupta 2018-01-31 16:03:25 -05:00
parent b1adc0e137
commit e8fb82d672
26 changed files with 488 additions and 364 deletions

View File

@ -35,10 +35,7 @@ Option A:
all the assumptions the script is making. The script can be found at
https://github.com/staktrace/moz-scripts/blob/master/try-latest-webrender.sh
and contains documentation on how to use it. Read the documentation carefully
before trying to use it. The only extra change you need to make with this
option is to manually update the revision in gfx/webrender_bindings/revision.txt
so that it points to the new WR version you are landing. The script doesn't
do that yet.
before trying to use it.
Option B:
Do the update manually. This is a little more cumbersome but may be required

View File

@ -226,7 +226,7 @@ impl Example for App {
BorderRadius::uniform(20.0),
ClipMode::Clip
);
let id = builder.define_clip(None, bounds, vec![complex], Some(mask));
let id = builder.define_clip(bounds, vec![complex], Some(mask));
builder.push_clip_id(id);
let info = LayoutPrimitiveInfo::new((100, 100).to(200, 200));

View File

@ -90,7 +90,7 @@ fn render_blob(
}
_ => {
return Err(api::BlobImageError::Other(
format!("Usupported image format {:?}", descriptor.format),
format!("Usupported image format"),
));
}
}

View File

@ -109,7 +109,6 @@ impl Example for App {
// and once at a margin of 10px from the top, for 60 pixels of
// scrolling.
let sticky_id = builder.define_sticky_frame(
None,
(50, 350).by(50, 50),
SideOffsets2D::new(Some(10.0), None, Some(10.0), None),
StickyOffsetBounds::new(-40.0, 60.0),

View File

@ -724,7 +724,8 @@ impl AlphaBatcher {
};
if cache_item.texture_id == SourceTexture::Invalid {
warn!("Warnings: skip a PrimitiveKind::Image at {:?}.\n", item_bounding_rect);
warn!("Warnings: skip a PrimitiveKind::Image");
debug!("at {:?}.", item_bounding_rect);
return;
}
@ -1183,7 +1184,8 @@ impl AlphaBatcher {
);
if cache_item.texture_id == SourceTexture::Invalid {
warn!("Warnings: skip a PrimitiveKind::YuvImage at {:?}.\n", item_bounding_rect);
warn!("Warnings: skip a PrimitiveKind::YuvImage");
debug!("at {:?}.", item_bounding_rect);
return;
}
@ -1523,7 +1525,8 @@ impl ClipBatcher {
..instance
});
} else {
warn!("Warnings: skip a image mask. Key:{:?} Rect::{:?}.\n", mask.image, mask.rect);
warn!("Warnings: skip a image mask");
debug!("Key:{:?} Rect::{:?}", mask.image, mask.rect);
continue;
}
}

View File

@ -2,10 +2,10 @@
* 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 api::{ClipId, DevicePixelScale, LayerPixel, LayerPoint, LayerRect, LayerSize};
use api::{LayerToWorldTransform, LayerTransform, LayerVector2D, LayoutTransform, LayoutVector2D};
use api::{PipelineId, PropertyBinding, ScrollClamping, ScrollEventPhase, ScrollLocation};
use api::{ScrollSensitivity, StickyOffsetBounds, WorldPoint};
use api::{ClipId, DevicePixelScale, ExternalScrollId, IdType, LayerPixel, LayerPoint, LayerRect};
use api::{LayerSize, LayerToWorldTransform, LayerTransform, LayerVector2D, LayoutTransform};
use api::{LayoutVector2D, PipelineId, PropertyBinding, ScrollClamping, ScrollEventPhase};
use api::{ScrollLocation, ScrollSensitivity, StickyOffsetBounds, WorldPoint};
use clip::{ClipSourcesHandle, ClipStore};
use clip_scroll_tree::{CoordinateSystemId, TransformUpdateState};
use euclid::SideOffsets2D;
@ -60,7 +60,7 @@ pub enum NodeType {
/// Transforms it's content, but doesn't clip it. Can also be adjusted
/// by scroll events or setting scroll offsets.
ScrollFrame(ScrollingState),
ScrollFrame(ScrollFrameInfo),
/// A special kind of node that adjusts its position based on the position
/// of its parent node and a given set of sticky positioning offset bounds.
@ -153,16 +153,18 @@ impl ClipScrollNode {
pub fn new_scroll_frame(
pipeline_id: PipelineId,
parent_id: ClipId,
external_id: Option<ExternalScrollId>,
frame_rect: &LayerRect,
content_size: &LayerSize,
scroll_sensitivity: ScrollSensitivity,
) -> Self {
let node_type = NodeType::ScrollFrame(ScrollingState::new(
let node_type = NodeType::ScrollFrame(ScrollFrameInfo::new(
scroll_sensitivity,
LayerSize::new(
(content_size.width - frame_rect.size.width).max(0.0),
(content_size.height - frame_rect.size.height).max(0.0)
)
),
external_id,
));
Self::new(pipeline_id, Some(parent_id), frame_rect, node_type)
@ -211,7 +213,7 @@ impl ClipScrollNode {
self.children.push(child);
}
pub fn apply_old_scrolling_state(&mut self, old_scrolling_state: &ScrollingState) {
pub fn apply_old_scrolling_state(&mut self, old_scrolling_state: &ScrollFrameInfo) {
match self.node_type {
NodeType::ScrollFrame(ref mut scrolling) => {
let scroll_sensitivity = scrolling.scroll_sensitivity;
@ -765,10 +767,22 @@ impl ClipScrollNode {
_ => false,
}
}
pub fn matches_id(&self, node_id: ClipId, id_to_match: IdType) -> bool {
let external_id = match id_to_match {
IdType::ExternalScrollId(id) => id,
IdType::ClipId(clip_id) => return node_id == clip_id,
};
match self.node_type {
NodeType::ScrollFrame(info) if info.external_id == Some(external_id) => true,
_ => false,
}
}
}
#[derive(Copy, Clone, Debug)]
pub struct ScrollingState {
pub struct ScrollFrameInfo {
pub offset: LayerVector2D,
pub spring: Spring,
pub started_bouncing_back: bool,
@ -779,14 +793,21 @@ pub struct ScrollingState {
/// Amount that this ScrollFrame can scroll in both directions.
pub scrollable_size: LayerSize,
/// An external id to identify this scroll frame to API clients. This
/// allows setting scroll positions via the API without relying on ClipsIds
/// which may change between frames.
pub external_id: Option<ExternalScrollId>,
}
/// Manages scrolling offset, overscroll state, etc.
impl ScrollingState {
pub fn new(scroll_sensitivity: ScrollSensitivity,
scrollable_size: LayerSize
) -> ScrollingState {
ScrollingState {
impl ScrollFrameInfo {
pub fn new(
scroll_sensitivity: ScrollSensitivity,
scrollable_size: LayerSize,
external_id: Option<ExternalScrollId>,
) -> ScrollFrameInfo {
ScrollFrameInfo {
offset: LayerVector2D::zero(),
spring: Spring::at(LayerPoint::zero(), STIFFNESS, DAMPING),
started_bouncing_back: false,
@ -794,6 +815,7 @@ impl ScrollingState {
should_handoff_scroll: false,
scroll_sensitivity,
scrollable_size,
external_id,
}
}

View File

@ -2,11 +2,12 @@
* 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 api::{ClipId, ClipChainId, DeviceIntRect, DevicePixelScale, LayerPoint, LayerRect};
use api::{LayerToWorldTransform, LayerVector2D, LayoutTransform, PipelineId, PropertyBinding};
use api::{ScrollClamping, ScrollEventPhase, ScrollLayerState, ScrollLocation, WorldPoint};
use api::{ClipChainId, ClipId, DeviceIntRect, DevicePixelScale, ExternalScrollId, IdType};
use api::{LayerPoint, LayerRect, LayerToWorldTransform, LayerVector2D, LayoutTransform};
use api::{PipelineId, PropertyBinding, ScrollClamping, ScrollEventPhase, ScrollLocation};
use api::{ScrollNodeState, WorldPoint};
use clip::ClipStore;
use clip_scroll_node::{ClipScrollNode, NodeType, ScrollingState, StickyFrameInfo};
use clip_scroll_node::{ClipScrollNode, NodeType, ScrollFrameInfo, StickyFrameInfo};
use gpu_cache::GpuCache;
use gpu_types::{ClipScrollNodeIndex, ClipScrollNodeData};
use internal_types::{FastHashMap, FastHashSet};
@ -16,7 +17,7 @@ use resource_cache::ResourceCache;
use scene::SceneProperties;
use util::TransformOrOffset;
pub type ScrollStates = FastHashMap<ClipId, ScrollingState>;
pub type ScrollStates = FastHashMap<ExternalScrollId, ScrollFrameInfo>;
/// An id that identifies coordinate systems in the ClipScrollTree. Each
/// coordinate system has an id and those ids will be shared when the coordinates
@ -59,7 +60,7 @@ pub struct ClipScrollTree {
/// A HashMap of built ClipChains that are described by `clip_chains_descriptors`.
pub clip_chains: FastHashMap<ClipChainId, ClipChain>,
pub pending_scroll_offsets: FastHashMap<ClipId, (LayerPoint, ScrollClamping)>,
pub pending_scroll_offsets: FastHashMap<IdType, (LayerPoint, ScrollClamping)>,
/// The ClipId of the currently scrolling node. Used to allow the same
/// node to scroll even if a touch operation leaves the boundaries of that node.
@ -234,14 +235,13 @@ impl ClipScrollTree {
true
}
pub fn get_scroll_node_state(&self) -> Vec<ScrollLayerState> {
pub fn get_scroll_node_state(&self) -> Vec<ScrollNodeState> {
let mut result = vec![];
for (id, node) in self.nodes.iter() {
if let NodeType::ScrollFrame(scrolling) = node.node_type {
result.push(ScrollLayerState {
id: *id,
scroll_offset: scrolling.offset,
})
for node in self.nodes.values() {
if let NodeType::ScrollFrame(info) = node.node_type {
if let Some(id) = info.external_id {
result.push(ScrollNodeState { id, scroll_offset: info.offset })
}
}
}
result
@ -251,13 +251,16 @@ impl ClipScrollTree {
self.current_new_node_item = 1;
let mut scroll_states = FastHashMap::default();
for (layer_id, old_node) in &mut self.nodes.drain() {
if self.pipelines_to_discard.contains(&layer_id.pipeline_id()) {
for (node_id, old_node) in &mut self.nodes.drain() {
if self.pipelines_to_discard.contains(&node_id.pipeline_id()) {
continue;
}
if let NodeType::ScrollFrame(scrolling) = old_node.node_type {
scroll_states.insert(layer_id, scrolling);
match old_node.node_type {
NodeType::ScrollFrame(info) if info.external_id.is_some() => {
scroll_states.insert(info.external_id.unwrap(), info);
}
_ => {}
}
}
@ -267,15 +270,12 @@ impl ClipScrollTree {
scroll_states
}
pub fn scroll_node(&mut self, origin: LayerPoint, id: ClipId, clamp: ScrollClamping) -> bool {
if self.nodes.is_empty() {
self.pending_scroll_offsets.insert(id, (origin, clamp));
return false;
}
if let Some(node) = self.nodes.get_mut(&id) {
pub fn scroll_node(&mut self, origin: LayerPoint, id: IdType, clamp: ScrollClamping) -> bool {
for (clip_id, node) in &mut self.nodes {
if node.matches_id(*clip_id, id) {
return node.set_scroll_origin(&origin, clamp);
}
}
self.pending_scroll_offsets.insert(id, (origin, clamp));
false
@ -491,16 +491,30 @@ impl ClipScrollTree {
}
pub fn finalize_and_apply_pending_scroll_offsets(&mut self, old_states: ScrollStates) {
// TODO(gw): These are all independent - can be run through thread pool if it shows up
// in the profile!
for (clip_id, node) in &mut self.nodes {
if let Some(scrolling_state) = old_states.get(clip_id) {
let external_id = match node.node_type {
NodeType::ScrollFrame(info) if info.external_id.is_some() => info.external_id,
_ => None,
};
if let Some(external_id) = external_id {
if let Some(scrolling_state) = old_states.get(&external_id) {
node.apply_old_scrolling_state(scrolling_state);
}
if let Some((pending_offset, clamping)) = self.pending_scroll_offsets.remove(clip_id) {
node.set_scroll_origin(&pending_offset, clamping);
}
let id = IdType::ClipId(*clip_id);
if let Some((offset, clamping)) = self.pending_scroll_offsets.remove(&id) {
node.set_scroll_origin(&offset, clamping);
}
if let Some(external_id) = external_id {
let id = IdType::ExternalScrollId(external_id);
if let Some((offset, clamping)) = self.pending_scroll_offsets.remove(&id) {
node.set_scroll_origin(&offset, clamping);
}
}
}
}

View File

@ -760,17 +760,17 @@ impl Device {
shader_type: gl::GLenum,
source: &String,
) -> Result<gl::GLuint, ShaderError> {
debug!("compile {:?}", name);
debug!("compile {}", name);
let id = gl.create_shader(shader_type);
gl.shader_source(id, &[source.as_bytes()]);
gl.compile_shader(id);
let log = gl.get_shader_info_log(id);
if gl.get_shader_iv(id, gl::COMPILE_STATUS) == (0 as gl::GLint) {
println!("Failed to compile shader: {:?}\n{}", name, log);
println!("Failed to compile shader: {}\n{}", name, log);
Err(ShaderError::Compilation(name.to_string(), log))
} else {
if !log.is_empty() {
println!("Warnings detected on shader: {:?}\n{}", name, log);
println!("Warnings detected on shader: {}\n{}", name, log);
}
Ok(id)
}
@ -1317,7 +1317,7 @@ impl Device {
if self.gl.get_program_iv(pid, gl::LINK_STATUS) == (0 as gl::GLint) {
let error_log = self.gl.get_program_info_log(pid);
println!(
"Failed to load a program object with a program binary: {:?} renderer {}\n{}",
"Failed to load a program object with a program binary: {} renderer {}\n{}",
base_filename,
self.renderer_name,
error_log
@ -1379,7 +1379,7 @@ impl Device {
if self.gl.get_program_iv(pid, gl::LINK_STATUS) == (0 as gl::GLint) {
let error_log = self.gl.get_program_info_log(pid);
println!(
"Failed to link shader program: {:?}\n{}",
"Failed to link shader program: {}\n{}",
base_filename,
error_log
);

View File

@ -4,13 +4,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BuiltDisplayListIter, ClipAndScrollInfo, ClipId, ColorF, ComplexClipRegion};
use api::{DevicePixelScale, DeviceUintRect, DeviceUintSize};
use api::{DisplayItemRef, DocumentLayer, Epoch, FilterOp};
use api::{ImageDisplayItem, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect};
use api::{LayerSize, LayerVector2D, LayoutSize};
use api::{LocalClip, PipelineId, ScrollClamping, ScrollEventPhase, ScrollLayerState};
use api::{ScrollLocation, ScrollPolicy, ScrollSensitivity, SpecificDisplayItem, StackingContext};
use api::{TileOffset, TransformStyle, WorldPoint};
use api::{DevicePixelScale, DeviceUintRect, DeviceUintSize, DisplayItemRef, DocumentLayer, Epoch};
use api::{ExternalScrollId, FilterOp, IdType, ImageDisplayItem, ItemRange, LayerPoint};
use api::{LayerPrimitiveInfo, LayerRect, LayerSize, LayerVector2D, LayoutSize, LocalClip};
use api::{PipelineId, ScrollClamping, ScrollEventPhase, ScrollLocation, ScrollNodeState};
use api::{ScrollPolicy, ScrollSensitivity, SpecificDisplayItem, StackingContext, TileOffset};
use api::{TransformStyle, WorldPoint};
use clip::ClipRegion;
use clip_scroll_node::StickyFrameInfo;
use clip_scroll_tree::{ClipScrollTree, ScrollStates};
@ -205,6 +204,7 @@ impl<'a> FlattenContext<'a> {
pipeline_id: PipelineId,
parent_id: &ClipId,
new_scroll_frame_id: &ClipId,
external_id: Option<ExternalScrollId>,
frame_rect: &LayerRect,
content_rect: &LayerRect,
clip_region: ClipRegion,
@ -222,6 +222,7 @@ impl<'a> FlattenContext<'a> {
self.builder.add_scroll_frame(
*new_scroll_frame_id,
clip_id,
external_id,
pipeline_id,
&frame_rect,
&content_rect.size,
@ -371,6 +372,7 @@ impl<'a> FlattenContext<'a> {
self.builder.add_scroll_frame(
ClipId::root_scroll_node(pipeline_id),
iframe_reference_frame_id,
Some(ExternalScrollId(0, pipeline_id)),
pipeline_id,
&iframe_rect,
&pipeline.content_size,
@ -458,7 +460,8 @@ impl<'a> FlattenContext<'a> {
);
}
None => {
warn!("Unknown font instance key: {:?}", text_info.font_key);
warn!("Unknown font instance key");
debug!("key={:?}", text_info.font_key);
}
}
}
@ -603,6 +606,7 @@ impl<'a> FlattenContext<'a> {
pipeline_id,
&clip_and_scroll.scroll_node_id,
&info.id,
info.external_id,
&frame_rect,
&content_rect,
clip_region,
@ -981,12 +985,12 @@ impl FrameContext {
&self.clip_scroll_tree
}
pub fn get_scroll_node_state(&self) -> Vec<ScrollLayerState> {
pub fn get_scroll_node_state(&self) -> Vec<ScrollNodeState> {
self.clip_scroll_tree.get_scroll_node_state()
}
/// Returns true if the node actually changed position or false otherwise.
pub fn scroll_node(&mut self, origin: LayerPoint, id: ClipId, clamp: ScrollClamping) -> bool {
pub fn scroll_node(&mut self, origin: LayerPoint, id: IdType, clamp: ScrollClamping) -> bool {
self.clip_scroll_tree.scroll_node(origin, id, clamp)
}

View File

@ -2,15 +2,15 @@
* 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 api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayList, ClipAndScrollInfo, ClipId};
use api::{ColorF, ColorU, DeviceIntPoint, DevicePixelScale, DeviceUintPoint, DeviceUintRect};
use api::{DeviceUintSize, DocumentLayer, ExtendMode, FontRenderMode, GlyphInstance, GlyphOptions};
use api::{GradientStop, HitTestFlags, HitTestItem, HitTestResult, ImageKey, ImageRendering};
use api::{Epoch, ItemRange, ItemTag, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize};
use api::{LayerTransform, LayerVector2D, LayoutTransform, LayoutVector2D, LineOrientation};
use api::{LineStyle, LocalClip, PipelineId, PremultipliedColorF, PropertyBinding, RepeatMode};
use api::{ScrollSensitivity, Shadow, TexelRect, TileOffset, TransformStyle, WorldPoint};
use api::{DeviceIntRect, DeviceIntSize, YuvColorSpace, YuvData};
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayList, ClipAndScrollInfo};
use api::{ClipId, ColorF, ColorU, DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixelScale};
use api::{DeviceUintPoint, DeviceUintRect, DeviceUintSize, DocumentLayer, Epoch, ExtendMode};
use api::{ExternalScrollId, FontRenderMode, GlyphInstance, GlyphOptions, GradientStop};
use api::{HitTestFlags, HitTestItem, HitTestResult, ImageKey, ImageRendering, ItemRange, ItemTag};
use api::{LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize, LayerTransform, LayerVector2D};
use api::{LayoutTransform, LayoutVector2D, LineOrientation, LineStyle, LocalClip, PipelineId};
use api::{PremultipliedColorF, PropertyBinding, RepeatMode, ScrollSensitivity, Shadow, TexelRect};
use api::{TileOffset, TransformStyle, WorldPoint, WorldToLayerTransform, YuvColorSpace, YuvData};
use app_units::Au;
use border::ImageBorderSegment;
use clip::{ClipRegion, ClipSource, ClipSources, ClipStore, Contains};
@ -25,9 +25,9 @@ use internal_types::{FastHashMap, FastHashSet, RenderPassIndex};
use picture::{ContentOrigin, PictureCompositeMode, PictureKind, PicturePrimitive, PictureSurface};
use prim_store::{BrushKind, BrushPrimitive, ImageCacheKey, YuvImagePrimitiveCpu};
use prim_store::{GradientPrimitiveCpu, ImagePrimitiveCpu, ImageSource, PrimitiveKind};
use prim_store::{PrimitiveContainer, PrimitiveIndex, SpecificPrimitiveIndex};
use prim_store::{PrimitiveContainer, PrimitiveIndex};
use prim_store::{PrimitiveStore, RadialGradientPrimitiveCpu};
use prim_store::{BrushSegmentDescriptor, TextRunPrimitiveCpu};
use prim_store::{BrushSegmentDescriptor, PrimitiveRun, TextRunPrimitiveCpu};
use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters};
use render_task::{ClearMode, ClipChain, RenderTask, RenderTaskId, RenderTaskTree};
use resource_cache::ResourceCache;
@ -144,8 +144,29 @@ pub struct FrameState<'a> {
pub gpu_cache: &'a mut GpuCache,
}
pub struct PrimitiveRunContext<'a> {
pub struct PictureContext<'a> {
pub pipeline_id: PipelineId,
pub perform_culling: bool,
pub prim_runs: Vec<PrimitiveRun>,
pub original_reference_frame_id: Option<ClipId>,
pub display_list: &'a BuiltDisplayList,
pub draw_text_transformed: bool,
pub inv_world_transform: Option<WorldToLayerTransform>,
}
pub struct PictureState {
pub tasks: Vec<RenderTaskId>,
}
impl PictureState {
pub fn new() -> PictureState {
PictureState {
tasks: Vec::new(),
}
}
}
pub struct PrimitiveRunContext<'a> {
pub clip_chain: Option<&'a ClipChain>,
pub scroll_node: &'a ClipScrollNode,
pub clip_chain_rect_index: ClipChainRectIndex,
@ -153,13 +174,11 @@ pub struct PrimitiveRunContext<'a> {
impl<'a> PrimitiveRunContext<'a> {
pub fn new(
display_list: &'a BuiltDisplayList,
clip_chain: Option<&'a ClipChain>,
scroll_node: &'a ClipScrollNode,
clip_chain_rect_index: ClipChainRectIndex,
) -> Self {
PrimitiveRunContext {
display_list,
clip_chain,
scroll_node,
clip_chain_rect_index,
@ -651,6 +670,7 @@ impl FrameBuilder {
self.add_scroll_frame(
topmost_scrolling_node_id,
clip_scroll_tree.root_reference_frame_id,
Some(ExternalScrollId(0, pipeline_id)),
pipeline_id,
&viewport_rect,
content_size,
@ -683,6 +703,7 @@ impl FrameBuilder {
&mut self,
new_node_id: ClipId,
parent_id: ClipId,
external_id: Option<ExternalScrollId>,
pipeline_id: PipelineId,
frame_rect: &LayerRect,
content_size: &LayerSize,
@ -692,6 +713,7 @@ impl FrameBuilder {
let node = ClipScrollNode::new_scroll_frame(
pipeline_id,
parent_id,
external_id,
frame_rect,
content_size,
scroll_sensitivity,
@ -1612,7 +1634,6 @@ impl FrameBuilder {
}
// The root picture is always the first one added.
let prim_run_cmds = mem::replace(&mut self.prim_store.cpu_pictures[0].runs, Vec::new());
let root_clip_scroll_node = &clip_scroll_tree.nodes[&clip_scroll_tree.root_reference_frame_id()];
let display_list = &pipelines
@ -1638,29 +1659,28 @@ impl FrameBuilder {
gpu_cache,
};
let root_prim_run_context = PrimitiveRunContext::new(
let pic_context = PictureContext {
pipeline_id: root_clip_scroll_node.pipeline_id,
perform_culling: true,
prim_runs: mem::replace(&mut self.prim_store.cpu_pictures[0].runs, Vec::new()),
original_reference_frame_id: None,
display_list,
root_clip_scroll_node.clip_chain.as_ref(),
root_clip_scroll_node,
ClipChainRectIndex(0),
);
draw_text_transformed: true,
inv_world_transform: None,
};
let mut pic_state = PictureState::new();
let mut child_tasks = Vec::new();
self.prim_store.reset_prim_visibility();
self.prim_store.prepare_prim_runs(
&prim_run_cmds,
root_clip_scroll_node.pipeline_id,
&root_prim_run_context,
true,
&mut child_tasks,
None,
SpecificPrimitiveIndex(0),
&pic_context,
&mut pic_state,
&frame_context,
&mut frame_state,
);
let pic = &mut self.prim_store.cpu_pictures[0];
pic.runs = prim_run_cmds;
pic.runs = pic_context.prim_runs;
let root_render_task = RenderTask::new_picture(
None,
@ -1669,7 +1689,7 @@ impl FrameBuilder {
ContentOrigin::Screen(DeviceIntPoint::zero()),
PremultipliedColorF::TRANSPARENT,
ClearMode::Transparent,
child_tasks,
pic_state.tasks,
PictureType::Image,
);

View File

@ -7,7 +7,7 @@ use api::{DeviceIntPoint, DeviceIntRect, LayerToWorldScale, PipelineId};
use api::{BoxShadowClipMode, LayerPoint, LayerRect, LayerVector2D, Shadow};
use api::{ClipId, PremultipliedColorF};
use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowCacheKey};
use frame_builder::{FrameContext, FrameState};
use frame_builder::{FrameContext, FrameState, PictureState};
use gpu_cache::GpuDataRequest;
use gpu_types::{BrushImageKind, PictureType};
use prim_store::{BrushKind, BrushPrimitive, PrimitiveIndex, PrimitiveRun, PrimitiveRunLocalRect};
@ -331,8 +331,8 @@ impl PicturePrimitive {
prim_index: PrimitiveIndex,
prim_screen_rect: &DeviceIntRect,
prim_local_rect: &LayerRect,
child_tasks: Vec<RenderTaskId>,
parent_tasks: &mut Vec<RenderTaskId>,
pic_state_for_children: PictureState,
pic_state: &mut PictureState,
frame_context: &FrameContext,
frame_state: &mut FrameState,
) {
@ -354,7 +354,7 @@ impl PicturePrimitive {
content_origin,
PremultipliedColorF::TRANSPARENT,
ClearMode::Transparent,
child_tasks,
pic_state_for_children.tasks,
PictureType::Image,
);
@ -371,7 +371,7 @@ impl PicturePrimitive {
);
let render_task_id = frame_state.render_tasks.add(blur_render_task);
parent_tasks.push(render_task_id);
pic_state.tasks.push(render_task_id);
self.surface = Some(PictureSurface::RenderTask(render_task_id));
}
Some(PictureCompositeMode::Filter(FilterOp::DropShadow(offset, blur_radius, color))) => {
@ -383,7 +383,7 @@ impl PicturePrimitive {
ContentOrigin::Screen(rect.origin),
PremultipliedColorF::TRANSPARENT,
ClearMode::Transparent,
child_tasks,
pic_state_for_children.tasks,
PictureType::Image,
);
@ -402,7 +402,7 @@ impl PicturePrimitive {
*secondary_render_task_id = Some(picture_task_id);
let render_task_id = frame_state.render_tasks.add(blur_render_task);
parent_tasks.push(render_task_id);
pic_state.tasks.push(render_task_id);
self.surface = Some(PictureSurface::RenderTask(render_task_id));
}
Some(PictureCompositeMode::MixBlend(..)) => {
@ -413,17 +413,17 @@ impl PicturePrimitive {
content_origin,
PremultipliedColorF::TRANSPARENT,
ClearMode::Transparent,
child_tasks,
pic_state_for_children.tasks,
PictureType::Image,
);
let readback_task_id = frame_state.render_tasks.add(RenderTask::new_readback(*prim_screen_rect));
*secondary_render_task_id = Some(readback_task_id);
parent_tasks.push(readback_task_id);
pic_state.tasks.push(readback_task_id);
let render_task_id = frame_state.render_tasks.add(picture_task);
parent_tasks.push(render_task_id);
pic_state.tasks.push(render_task_id);
self.surface = Some(PictureSurface::RenderTask(render_task_id));
}
Some(PictureCompositeMode::Filter(filter)) => {
@ -433,7 +433,7 @@ impl PicturePrimitive {
// when opacity == 1.0, but can also occur on other
// filters and be a significant performance win.
if filter.is_noop() {
parent_tasks.extend(child_tasks);
pic_state.tasks.extend(pic_state_for_children.tasks);
self.surface = None;
} else {
let picture_task = RenderTask::new_picture(
@ -443,12 +443,12 @@ impl PicturePrimitive {
content_origin,
PremultipliedColorF::TRANSPARENT,
ClearMode::Transparent,
child_tasks,
pic_state_for_children.tasks,
PictureType::Image,
);
let render_task_id = frame_state.render_tasks.add(picture_task);
parent_tasks.push(render_task_id);
pic_state.tasks.push(render_task_id);
self.surface = Some(PictureSurface::RenderTask(render_task_id));
}
}
@ -460,16 +460,16 @@ impl PicturePrimitive {
content_origin,
PremultipliedColorF::TRANSPARENT,
ClearMode::Transparent,
child_tasks,
pic_state_for_children.tasks,
PictureType::Image,
);
let render_task_id = frame_state.render_tasks.add(picture_task);
parent_tasks.push(render_task_id);
pic_state.tasks.push(render_task_id);
self.surface = Some(PictureSurface::RenderTask(render_task_id));
}
None => {
parent_tasks.extend(child_tasks);
pic_state.tasks.extend(pic_state_for_children.tasks);
self.surface = None;
}
}
@ -516,7 +516,7 @@ impl PicturePrimitive {
);
let render_task_id = frame_state.render_tasks.add(blur_render_task);
parent_tasks.push(render_task_id);
pic_state.tasks.push(render_task_id);
self.surface = Some(PictureSurface::RenderTask(render_task_id));
}
PictureKind::BoxShadow { blur_radius, clip_mode, color, content_rect, cache_key, .. } => {
@ -576,7 +576,7 @@ impl PicturePrimitive {
);
let root_task_id = render_tasks.add(blur_render_task);
parent_tasks.push(root_task_id);
pic_state.tasks.push(root_task_id);
// TODO(gw): Remove the nastiness with having to pass
// the scale factor through the texture cache

View File

@ -191,7 +191,8 @@ impl FontContext {
},
);
} else {
println!("WARN: webrender failed to load font {:?}", font_key);
println!("WARN: webrender failed to load font");
debug!("font={:?}", font_key);
}
}
}
@ -217,7 +218,8 @@ impl FontContext {
},
);
} else {
println!("WARN: webrender failed to load font {:?} from path {:?}", font_key, pathname);
println!("WARN: webrender failed to load font");
debug!("font={:?}, path={:?}", font_key, pathname);
}
}
}
@ -331,13 +333,15 @@ impl FontContext {
FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE |
FT_Glyph_Format::FT_GLYPH_FORMAT_BITMAP => Some(slot),
_ => {
error!("Unsupported {:?}", format);
error!("Unsupported format");
debug!("format={:?}", format);
None
}
}
} else {
error!(
"Unable to load glyph for {} of size {:?} from font {:?}, {:?}",
error!("Unable to load glyph");
debug!(
"{} of size {:?} from font {:?}, {:?}",
glyph.index,
font.size,
font.font_key,
@ -564,8 +568,9 @@ impl FontContext {
};
let result = unsafe { FT_Render_Glyph(slot, render_mode) };
if !result.succeeded() {
error!(
"Unable to rasterize {:?} with {:?}, {:?}",
error!("Unable to rasterize");
debug!(
"{:?} with {:?}, {:?}",
key,
render_mode,
result
@ -611,12 +616,13 @@ impl FontContext {
}
}
_ => {
error!("Unsupported {:?}", format);
error!("Unsupported format");
debug!("format={:?}", format);
return None;
}
};
info!(
debug!(
"Rasterizing {:?} as {:?} with dimensions {:?}",
key,
font.render_mode,
@ -639,7 +645,7 @@ impl FontContext {
FT_Pixel_Mode::FT_PIXEL_MODE_BGRA => {
(bitmap.width as usize, bitmap.rows as usize)
}
_ => panic!("Unsupported {:?}", pixel_mode),
_ => panic!("Unsupported mode"),
};
let mut final_buffer = vec![0u8; actual_width * actual_height * 4];
@ -717,7 +723,7 @@ impl FontContext {
let src_slice = unsafe { slice::from_raw_parts(src, dest_slice.len()) };
dest_slice.copy_from_slice(src_slice);
}
_ => panic!("Unsupported {:?}", pixel_mode),
_ => panic!("Unsupported mode"),
}
src_row = unsafe { src_row.offset(bitmap.pitch as isize) };
dest = row_end;

View File

@ -2,18 +2,18 @@
* 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 api::{AlphaType, BorderRadius, BuiltDisplayList, ClipAndScrollInfo, ClipId, ClipMode};
use api::{AlphaType, BorderRadius, BuiltDisplayList, ClipAndScrollInfo, ClipMode};
use api::{ColorF, ColorU, DeviceIntRect, DeviceIntSize, DevicePixelScale, Epoch};
use api::{ComplexClipRegion, ExtendMode, FontRenderMode};
use api::{GlyphInstance, GlyphKey, GradientStop, ImageKey, ImageRendering, ItemRange, ItemTag};
use api::{LayerPoint, LayerRect, LayerSize, LayerToWorldTransform, LayerVector2D, LineOrientation};
use api::{LineStyle, PipelineId, PremultipliedColorF, TileOffset};
use api::{LineStyle, PremultipliedColorF, TileOffset};
use api::{WorldToLayerTransform, YuvColorSpace, YuvFormat};
use border::{BorderCornerInstance, BorderEdgeKind};
use clip_scroll_tree::{CoordinateSystemId};
use clip_scroll_node::ClipScrollNode;
use clip::{ClipSource, ClipSourcesHandle};
use frame_builder::{FrameContext, FrameState, PrimitiveRunContext};
use frame_builder::{FrameContext, FrameState, PictureContext, PictureState, PrimitiveRunContext};
use glyph_rasterizer::{FontInstance, FontTransform};
use gpu_cache::{GpuBlockData, GpuCache, GpuCacheAddress, GpuCacheHandle, GpuDataRequest,
ToGpuBlocks};
@ -1145,9 +1145,9 @@ impl PrimitiveStore {
&mut self,
prim_index: PrimitiveIndex,
prim_run_context: &PrimitiveRunContext,
child_tasks: Vec<RenderTaskId>,
parent_tasks: &mut Vec<RenderTaskId>,
pic_index: SpecificPrimitiveIndex,
pic_state_for_children: PictureState,
pic_context: &PictureContext,
pic_state: &mut PictureState,
frame_context: &FrameContext,
frame_state: &mut FrameState,
) {
@ -1160,28 +1160,25 @@ impl PrimitiveStore {
prim_index,
metadata.screen_rect.as_ref().expect("bug: trying to draw an off-screen picture!?"),
&metadata.local_rect,
child_tasks,
parent_tasks,
pic_state_for_children,
pic_state,
frame_context,
frame_state,
);
}
PrimitiveKind::TextRun => {
let pic = &self.cpu_pictures[pic_index.0];
let text = &mut self.cpu_text_runs[metadata.cpu_prim_index.0];
// The transform only makes sense for screen space rasterization
let transform = match pic.kind {
PictureKind::BoxShadow { .. } => None,
PictureKind::TextShadow { .. } => None,
PictureKind::Image { .. } => {
let transform = if pic_context.draw_text_transformed {
Some(&prim_run_context.scroll_node.world_content_transform)
},
} else {
None
};
text.prepare_for_render(
frame_state.resource_cache,
frame_context.device_pixel_scale,
transform,
prim_run_context.display_list,
pic_context.display_list,
frame_state.gpu_cache,
);
}
@ -1272,7 +1269,7 @@ impl PrimitiveStore {
let target_to_cache_task_id = render_tasks.add(target_to_cache_task);
// Hook this into the render task tree at the right spot.
parent_tasks.push(target_to_cache_task_id);
pic_state.tasks.push(target_to_cache_task_id);
// Pass the image opacity, so that the cached render task
// item inherits the same opacity properties.
@ -1323,15 +1320,24 @@ impl PrimitiveStore {
}
PrimitiveKind::AlignedGradient => {
let gradient = &self.cpu_gradients[metadata.cpu_prim_index.0];
metadata.opacity = gradient.build_gpu_blocks_for_aligned(prim_run_context.display_list, request);
metadata.opacity = gradient.build_gpu_blocks_for_aligned(
pic_context.display_list,
request,
);
}
PrimitiveKind::AngleGradient => {
let gradient = &self.cpu_gradients[metadata.cpu_prim_index.0];
gradient.build_gpu_blocks_for_angle_radial(prim_run_context.display_list, request);
gradient.build_gpu_blocks_for_angle_radial(
pic_context.display_list,
request,
);
}
PrimitiveKind::RadialGradient => {
let gradient = &self.cpu_radial_gradients[metadata.cpu_prim_index.0];
gradient.build_gpu_blocks_for_angle_radial(prim_run_context.display_list, request);
gradient.build_gpu_blocks_for_angle_radial(
pic_context.display_list,
request,
);
}
PrimitiveKind::TextRun => {
let text = &self.cpu_text_runs[metadata.cpu_prim_index.0];
@ -1498,10 +1504,10 @@ impl PrimitiveStore {
&mut self,
prim_run_context: &PrimitiveRunContext,
prim_index: PrimitiveIndex,
tasks: &mut Vec<RenderTaskId>,
clips: &Vec<ClipWorkItem>,
combined_outer_rect: &DeviceIntRect,
has_clips_from_other_coordinate_systems: bool,
pic_state: &mut PictureState,
frame_context: &FrameContext,
frame_state: &mut FrameState,
) -> bool {
@ -1555,7 +1561,7 @@ impl PrimitiveStore {
);
let clip_task_id = frame_state.render_tasks.add(clip_task);
tasks.push(clip_task_id);
pic_state.tasks.push(clip_task_id);
clip_task_id
})
@ -1569,7 +1575,7 @@ impl PrimitiveStore {
prim_index: PrimitiveIndex,
prim_run_context: &PrimitiveRunContext,
prim_screen_rect: &DeviceIntRect,
tasks: &mut Vec<RenderTaskId>,
pic_state: &mut PictureState,
frame_context: &FrameContext,
frame_state: &mut FrameState,
) -> bool {
@ -1675,10 +1681,10 @@ impl PrimitiveStore {
if self.update_clip_task_for_brush(
prim_run_context,
prim_index,
tasks,
&clips,
&combined_outer_rect,
has_clips_from_other_coordinate_systems,
pic_state,
frame_context,
frame_state,
) {
@ -1693,7 +1699,7 @@ impl PrimitiveStore {
let clip_task_id = frame_state.render_tasks.add(clip_task);
self.cpu_metadata[prim_index.0].clip_task_id = Some(clip_task_id);
tasks.push(clip_task_id);
pic_state.tasks.push(clip_task_id);
true
}
@ -1702,51 +1708,26 @@ impl PrimitiveStore {
&mut self,
prim_index: PrimitiveIndex,
prim_run_context: &PrimitiveRunContext,
perform_culling: bool,
parent_tasks: &mut Vec<RenderTaskId>,
pic_index: SpecificPrimitiveIndex,
pic_context: &PictureContext,
pic_state: &mut PictureState,
frame_context: &FrameContext,
frame_state: &mut FrameState,
) -> Option<LayerRect> {
// Reset the visibility of this primitive.
let mut may_need_clip_mask = true;
let mut pic_state_for_children = PictureState::new();
// Do some basic checks first, that can early out
// without even knowing the local rect.
let (cpu_prim_index, dependencies, cull_children, may_need_clip_mask) = {
let metadata = &mut self.cpu_metadata[prim_index.0];
metadata.screen_rect = None;
let (prim_kind, cpu_prim_index) = {
let metadata = &self.cpu_metadata[prim_index.0];
if perform_culling &&
if pic_context.perform_culling &&
!metadata.is_backface_visible &&
prim_run_context.scroll_node.world_content_transform.is_backface_visible() {
return None;
}
let (dependencies, cull_children, may_need_clip_mask) = match metadata.prim_kind {
PrimitiveKind::Picture => {
let pic = &mut self.cpu_pictures[metadata.cpu_prim_index.0];
if !pic.resolve_scene_properties(frame_context.scene_properties) {
return None;
}
let (rfid, may_need_clip_mask) = match pic.kind {
PictureKind::Image { reference_frame_id, .. } => {
(Some(reference_frame_id), false)
}
_ => {
(None, true)
}
};
(Some((pic.pipeline_id, mem::replace(&mut pic.runs, Vec::new()), rfid)),
pic.cull_children,
may_need_clip_mask)
}
_ => {
(None, true, true)
}
};
(metadata.cpu_prim_index, dependencies, cull_children, may_need_clip_mask)
(metadata.prim_kind, metadata.cpu_prim_index)
};
// If we have dependencies, we need to prepare them first, in order
@ -1754,26 +1735,59 @@ impl PrimitiveStore {
// For example, scrolling may affect the location of an item in
// local space, which may force us to render this item on a larger
// picture target, if being composited.
let mut child_tasks = Vec::new();
if let Some((pipeline_id, dependencies, rfid)) = dependencies {
if let PrimitiveKind::Picture = prim_kind {
let pic_context_for_children = {
let pic = &mut self.cpu_pictures[cpu_prim_index.0];
if !pic.resolve_scene_properties(frame_context.scene_properties) {
return None;
}
let (draw_text_transformed, original_reference_frame_id) = match pic.kind {
PictureKind::Image { reference_frame_id, .. } => {
may_need_clip_mask = false;
(true, Some(reference_frame_id))
}
PictureKind::BoxShadow { .. } |
PictureKind::TextShadow { .. } => {
(false, None)
}
};
let display_list = &frame_context
.pipelines
.get(&pic.pipeline_id)
.expect("No display list?")
.display_list;
let inv_world_transform = prim_run_context
.scroll_node
.world_content_transform
.inverse();
PictureContext {
pipeline_id: pic.pipeline_id,
perform_culling: pic.cull_children,
prim_runs: mem::replace(&mut pic.runs, Vec::new()),
original_reference_frame_id,
display_list,
draw_text_transformed,
inv_world_transform,
}
};
let result = self.prepare_prim_runs(
&dependencies,
pipeline_id,
prim_run_context,
cull_children,
&mut child_tasks,
rfid,
cpu_prim_index,
&pic_context_for_children,
&mut pic_state_for_children,
frame_context,
frame_state,
);
let metadata = &mut self.cpu_metadata[prim_index.0];
// Restore the dependencies (borrow check dance)
let pic = &mut self.cpu_pictures[cpu_prim_index.0];
pic.runs = dependencies;
pic.runs = pic_context_for_children.prim_runs;
let metadata = &mut self.cpu_metadata[prim_index.0];
metadata.local_rect = pic.update_local_rect(
metadata.local_rect,
result,
@ -1791,7 +1805,7 @@ impl PrimitiveStore {
let local_rect = metadata.local_clip_rect.intersection(&metadata.local_rect);
let local_rect = match local_rect {
Some(local_rect) => local_rect,
None if perform_culling => return None,
None if pic_context.perform_culling => return None,
None => LayerRect::zero(),
};
@ -1807,7 +1821,7 @@ impl PrimitiveStore {
};
metadata.screen_rect = screen_bounding_rect.intersection(&clip_bounds);
if metadata.screen_rect.is_none() && perform_culling {
if metadata.screen_rect.is_none() && pic_context.perform_culling {
return None;
}
@ -1816,11 +1830,11 @@ impl PrimitiveStore {
(local_rect, screen_bounding_rect)
};
if perform_culling && may_need_clip_mask && !self.update_clip_task(
if pic_context.perform_culling && may_need_clip_mask && !self.update_clip_task(
prim_index,
prim_run_context,
&unclipped_device_rect,
parent_tasks,
pic_state,
frame_context,
frame_state,
) {
@ -1830,9 +1844,9 @@ impl PrimitiveStore {
self.prepare_prim_for_render_inner(
prim_index,
prim_run_context,
child_tasks,
parent_tasks,
pic_index,
pic_state_for_children,
pic_context,
pic_state,
frame_context,
frame_state,
);
@ -1850,13 +1864,8 @@ impl PrimitiveStore {
pub fn prepare_prim_runs(
&mut self,
runs: &[PrimitiveRun],
pipeline_id: PipelineId,
parent_prim_run_context: &PrimitiveRunContext,
perform_culling: bool,
parent_tasks: &mut Vec<RenderTaskId>,
original_reference_frame_id: Option<ClipId>,
pic_index: SpecificPrimitiveIndex,
pic_context: &PictureContext,
pic_state: &mut PictureState,
frame_context: &FrameContext,
frame_state: &mut FrameState,
) -> PrimitiveRunLocalRect {
@ -1865,7 +1874,7 @@ impl PrimitiveStore {
local_rect_in_original_parent_space: LayerRect::zero(),
};
for run in runs {
for run in &pic_context.prim_runs {
// TODO(gw): Perhaps we can restructure this to not need to create
// a new primitive context for every run (if the hash
// lookups ever show up in a profile).
@ -1876,15 +1885,15 @@ impl PrimitiveStore {
.clip_scroll_tree
.get_clip_chain(&run.clip_and_scroll.clip_node_id());
if perform_culling {
if pic_context.perform_culling {
if !scroll_node.invertible {
debug!("{:?} {:?}: position not invertible", run.base_prim_index, pipeline_id);
debug!("{:?} {:?}: position not invertible", run.base_prim_index, pic_context.pipeline_id);
continue;
}
match clip_chain {
Some(ref chain) if chain.combined_outer_screen_rect.is_empty() => {
debug!("{:?} {:?}: clipped out", run.base_prim_index, pipeline_id);
debug!("{:?} {:?}: clipped out", run.base_prim_index, pic_context.pipeline_id);
continue;
}
_ => {},
@ -1892,15 +1901,13 @@ impl PrimitiveStore {
}
let parent_relative_transform = parent_prim_run_context
.scroll_node
.world_content_transform
.inverse()
let parent_relative_transform = pic_context
.inv_world_transform
.map(|inv_parent| {
inv_parent.pre_mul(&scroll_node.world_content_transform)
});
let original_relative_transform = original_reference_frame_id
let original_relative_transform = pic_context.original_reference_frame_id
.and_then(|original_reference_frame_id| {
let parent = frame_context
.clip_scroll_tree
@ -1912,12 +1919,7 @@ impl PrimitiveStore {
})
});
let display_list = &frame_context.pipelines
.get(&pipeline_id)
.expect("No display list?")
.display_list;
let clip_chain_rect = match perform_culling {
let clip_chain_rect = match pic_context.perform_culling {
true => get_local_clip_rect_for_nodes(scroll_node, clip_chain),
false => None,
};
@ -1932,7 +1934,6 @@ impl PrimitiveStore {
};
let child_prim_run_context = PrimitiveRunContext::new(
display_list,
clip_chain,
scroll_node,
clip_chain_rect_index,
@ -1944,9 +1945,8 @@ impl PrimitiveStore {
if let Some(prim_local_rect) = self.prepare_prim_for_render(
prim_index,
&child_prim_run_context,
perform_culling,
parent_tasks,
pic_index,
pic_context,
pic_state,
frame_context,
frame_state,
) {

View File

@ -2,10 +2,10 @@
* 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 api::{ApiMsg, BuiltDisplayList, DebugCommand, DeviceIntPoint};
use api::{ApiMsg, BuiltDisplayList, ClearCache, DebugCommand};
#[cfg(feature = "debugger")]
use api::{BuiltDisplayListIter, SpecificDisplayItem};
use api::{DevicePixelScale, DeviceUintPoint, DeviceUintRect, DeviceUintSize};
use api::{DeviceIntPoint, DevicePixelScale, DeviceUintPoint, DeviceUintRect, DeviceUintSize};
use api::{DocumentId, DocumentLayer, DocumentMsg, HitTestFlags, HitTestResult};
use api::{IdNamespace, PipelineId, RenderNotifier, WorldPoint};
use api::channel::{MsgReceiver, MsgSender, PayloadReceiver, PayloadReceiverHelperMethods};
@ -563,7 +563,15 @@ impl RenderBackend {
}
}
ApiMsg::MemoryPressure => {
self.resource_cache.on_memory_pressure();
// This is drastic. It will basically flush everything out of the cache,
// and the next frame will have to rebuild all of its resources.
// We may want to look into something less extreme, but on the other hand this
// should only be used in situations where are running low enough on memory
// that we risk crashing if we don't do something about it.
// The advantage of clearing the cache completely is that it gets rid of any
// remaining fragmentation that could have persisted if we kept around the most
// recently used resources.
self.resource_cache.clear(ClearCache::all());
let pending_update = self.resource_cache.pending_updates();
let msg = ResultMsg::UpdateResources {
@ -575,6 +583,22 @@ impl RenderBackend {
}
ApiMsg::DebugCommand(option) => {
let msg = match option {
DebugCommand::EnableDualSourceBlending(enable) => {
// Set in the config used for any future documents
// that are created.
self.frame_config
.dual_source_blending_is_enabled = enable;
// Set for any existing documents.
for (_, doc) in &mut self.documents {
doc.frame_ctx
.frame_builder_config
.dual_source_blending_is_enabled = enable;
}
// We don't want to forward this message to the renderer.
continue;
}
DebugCommand::FetchDocuments => {
let json = self.get_docs_for_debugger();
ResultMsg::DebugOutput(DebugOutput::FetchDocuments(json))
@ -606,22 +630,10 @@ impl RenderBackend {
// Note: we can't pass `LoadCapture` here since it needs to arrive
// before the `PublishDocument` messages sent by `load_capture`.
continue
},
DebugCommand::EnableDualSourceBlending(enable) => {
// Set in the config used for any future documents
// that are created.
self.frame_config
.dual_source_blending_is_enabled = enable;
// Set for any existing documents.
for (_, doc) in &mut self.documents {
doc.frame_ctx
.frame_builder_config
.dual_source_blending_is_enabled = enable;
}
// We don't want to forward this message to the renderer.
continue;
DebugCommand::ClearCaches(mask) => {
self.resource_cache.clear(mask);
continue
}
_ => ResultMsg::DebugCommand(option),
};
@ -691,7 +703,7 @@ impl RenderBackend {
&mut profile_counters.resources,
);
info!("generated frame for document {:?} with {} passes",
debug!("generated frame for document {:?} with {} passes",
document_id, rendered_document.frame.passes.len());
let msg = ResultMsg::UpdateGpuCache(self.gpu_cache.extract_updates());
@ -863,12 +875,12 @@ impl RenderBackend {
) -> DebugOutput {
use capture::CaptureConfig;
info!("capture: saving {:?}", root);
debug!("capture: saving {:?}", root);
let (resources, deferred) = self.resource_cache.save_capture(&root);
let config = CaptureConfig::new(root, bits);
for (&id, doc) in &mut self.documents {
info!("\tdocument {:?}", id);
debug!("\tdocument {:?}", id);
if config.bits.contains(CaptureBits::SCENE) {
let file_name = format!("scene-{}-{}", (id.0).0, id.1);
config.serialize(&doc.scene, file_name);
@ -932,7 +944,7 @@ impl RenderBackend {
use capture::CaptureConfig;
use tiling::Frame;
info!("capture: loading {:?}", root);
debug!("capture: loading {:?}", root);
let backend = CaptureConfig::deserialize::<PlainRenderBackend, _>(root, "backend")
.expect("Unable to open backend.ron");
let caches_maybe = CaptureConfig::deserialize::<PlainCacheOwn, _>(root, "resource_cache");
@ -958,7 +970,7 @@ impl RenderBackend {
self.enable_render_on_scroll = backend.enable_render_on_scroll;
for (id, view) in backend.documents {
info!("\tdocument {:?}", id);
debug!("\tdocument {:?}", id);
let scene_name = format!("scene-{}-{}", (id.0).0, id.1);
let scene = CaptureConfig::deserialize::<Scene, _>(root, &scene_name)
.expect(&format!("Unable to open {}.ron", scene_name));

View File

@ -731,29 +731,37 @@ impl RenderTask {
}
#[derive(Debug, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum RenderTaskCacheKeyKind {
BoxShadow(BoxShadowCacheKey),
Image(ImageCacheKey),
}
#[derive(Debug, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct RenderTaskCacheKey {
pub size: DeviceIntSize,
pub kind: RenderTaskCacheKeyKind,
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
struct RenderTaskCacheEntry {
handle: TextureCacheHandle,
}
// A cache of render tasks that are stored in the texture
// cache for usage across frames.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct RenderTaskCache {
entries: FastHashMap<RenderTaskCacheKey, RenderTaskCacheEntry>,
}
impl RenderTaskCache {
pub fn new() -> RenderTaskCache {
pub fn new() -> Self {
RenderTaskCache {
entries: FastHashMap::default(),
}

View File

@ -720,7 +720,7 @@ impl SourceTextureResolver {
SourceTexture::External(external_image) => {
let texture = self.external_images
.get(&(external_image.id, external_image.channel_index))
.expect(&format!("BUG: External image should be resolved by now: {:?}", external_image));
.expect(&format!("BUG: External image should be resolved by now"));
device.bind_external_texture(sampler, texture);
}
SourceTexture::TextureCache(index) => {
@ -1192,7 +1192,7 @@ impl LazilyCompiledShader {
device.bind_program(program);
device.draw_triangles_u16(0, 3);
let t2 = precise_time_ns();
println!("[C: {:.1} ms D: {:.1} ms] Precache {} {:?}",
debug!("[C: {:.1} ms D: {:.1} ms] Precache {} {:?}",
(t1 - t0) as f64 / 1000000.0,
(t2 - t1) as f64 / 1000000.0,
name,
@ -2684,6 +2684,9 @@ impl Renderer {
DebugCommand::EnableGpuSampleQueries(enable) => {
self.set_debug_flag(DebugFlags::GPU_SAMPLE_QUERIES, enable);
}
DebugCommand::EnableDualSourceBlending(_) => {
panic!("Should be handled by render backend");
}
DebugCommand::FetchDocuments |
DebugCommand::FetchClipScrollTree => {}
DebugCommand::FetchRenderTasks => {
@ -2702,8 +2705,19 @@ impl Renderer {
DebugCommand::LoadCapture(..) => {
panic!("Capture commands are not welcome here! Did you build with 'capture' feature?")
}
DebugCommand::EnableDualSourceBlending(_) => {
panic!("Should be handled by render backend");
DebugCommand::ClearCaches(_) => {}
DebugCommand::InvalidateGpuCache => {
match self.gpu_cache_texture.bus {
CacheBus::PixelBuffer { ref mut rows, .. } => {
info!("Invalidating GPU caches");
for row in rows {
row.is_dirty = true;
}
}
CacheBus::Scatter { .. } => {
warn!("Unable to invalidate scattered GPU cache");
}
}
}
}
}
@ -4132,7 +4146,7 @@ impl Renderer {
let texture_target = match ext_image.image_type {
ExternalImageType::TextureHandle(target) => target,
ExternalImageType::Buffer => {
panic!("{:?} is not a suitable image type in update_deferred_resolves()", ext_image.image_type);
panic!("not a suitable image type in update_deferred_resolves()");
}
};
@ -4145,8 +4159,9 @@ impl Renderer {
ExternalTexture::new(texture_id, texture_target)
}
ExternalImageSource::Invalid => {
warn!(
"Invalid ext-image for ext_id:{:?}, channel:{}.",
warn!("Invalid ext-image");
debug!(
"For ext_id:{:?}, channel:{}.",
ext_image.id,
ext_image.channel_index
);

View File

@ -4,7 +4,7 @@
use api::{AddFont, BlobImageData, BlobImageResources, ResourceUpdate, ResourceUpdates};
use api::{BlobImageDescriptor, BlobImageError, BlobImageRenderer, BlobImageRequest};
use api::{ColorF, DevicePoint, DeviceUintRect, DeviceUintSize};
use api::{ClearCache, ColorF, DevicePoint, DeviceUintRect, DeviceUintSize};
use api::{Epoch, FontInstanceKey, FontKey, FontTemplate};
use api::{ExternalImageData, ExternalImageType};
use api::{FontInstanceOptions, FontInstancePlatformOptions, FontVariation};
@ -113,17 +113,12 @@ pub struct ImageTiling {
pub type TiledImageMap = FastHashMap<ImageKey, ImageTiling>;
#[derive(Default)]
struct ImageTemplates {
images: FastHashMap<ImageKey, ImageResource>,
}
impl ImageTemplates {
fn new() -> Self {
ImageTemplates {
images: FastHashMap::default(),
}
}
fn insert(&mut self, key: ImageKey, resource: ImageResource) {
self.images.insert(key, resource);
}
@ -232,6 +227,7 @@ impl Into<BlobImageRequest> for ImageRequest {
type ImageCache = ResourceClassCache<ImageRequest, CachedImageInfo>;
pub type FontInstanceMap = Arc<RwLock<FastHashMap<FontInstanceKey, FontInstance>>>;
#[derive(Default)]
struct Resources {
font_templates: FastHashMap<FontKey, FontTemplate>,
font_instances: FontInstanceMap,
@ -286,11 +282,7 @@ impl ResourceCache {
cached_glyphs: GlyphCache::new(),
cached_images: ResourceClassCache::new(),
cached_render_tasks: RenderTaskCache::new(),
resources: Resources {
font_templates: FastHashMap::default(),
font_instances: Arc::new(RwLock::new(FastHashMap::default())),
image_templates: ImageTemplates::new(),
},
resources: Resources::default(),
cached_glyph_dimensions: FastHashMap::default(),
texture_cache,
state: State::Idle,
@ -499,10 +491,7 @@ impl ResourceCache {
let max_texture_size = self.max_texture_size();
let image = match self.resources.image_templates.get_mut(image_key) {
Some(res) => res,
None => panic!(
"Attempt to update non-existent image (key {:?}).",
image_key
),
None => panic!("Attempt to update non-existent image"),
};
let mut tiling = image.tiling;
@ -541,7 +530,8 @@ impl ResourceCache {
self.blob_image_renderer.as_mut().unwrap().delete(image_key);
},
None => {
println!("Delete the non-exist key:{:?}", image_key);
warn!("Delete the non-exist key");
debug!("key={:?}", image_key);
}
}
}
@ -563,10 +553,8 @@ impl ResourceCache {
let template = match self.resources.image_templates.get(key) {
Some(template) => template,
None => {
warn!(
"ERROR: Trying to render deleted / non-existent key {:?}",
key
);
warn!("ERROR: Trying to render deleted / non-existent key");
debug!("key={:?}", key);
return
}
};
@ -942,19 +930,20 @@ impl ResourceCache {
self.state = State::Idle;
}
pub fn on_memory_pressure(&mut self) {
// This is drastic. It will basically flush everything out of the cache,
// and the next frame will have to rebuild all of its resources.
// We may want to look into something less extreme, but on the other hand this
// should only be used in situations where are running low enough on memory
// that we risk crashing if we don't do something about it.
// The advantage of clearing the cache completely is that it gets rid of any
// remaining fragmentation that could have persisted if we kept around the most
// recently used resources.
pub fn clear(&mut self, what: ClearCache) {
if what.contains(ClearCache::IMAGES) {
self.cached_images.clear();
}
if what.contains(ClearCache::GLYPHS) {
self.cached_glyphs.clear();
}
if what.contains(ClearCache::GLYPH_DIMENSIONS) {
self.cached_glyph_dimensions.clear();
}
if what.contains(ClearCache::RENDER_TASKS) {
self.cached_render_tasks.clear();
}
}
pub fn clear_namespace(&mut self, namespace: IdNamespace) {
self.resources
@ -1035,6 +1024,7 @@ pub struct PlainCacheRef<'a> {
glyphs: PlainGlyphCacheRef<'a>,
glyph_dimensions: &'a GlyphDimensionsCache,
images: &'a ImageCache,
render_tasks: &'a RenderTaskCache,
textures: &'a TextureCache,
}
@ -1045,6 +1035,7 @@ pub struct PlainCacheOwn {
glyphs: PlainGlyphCacheOwn,
glyph_dimensions: GlyphDimensionsCache,
images: ImageCache,
render_tasks: RenderTaskCache,
textures: TextureCache,
}
@ -1286,6 +1277,7 @@ impl ResourceCache {
.collect(),
glyph_dimensions: &self.cached_glyph_dimensions,
images: &self.cached_images,
render_tasks: &self.cached_render_tasks,
textures: &self.texture_cache,
}
}
@ -1350,6 +1342,8 @@ impl ResourceCache {
self.current_frame_id = cached.current_frame_id;
self.cached_glyphs = GlyphCache { glyph_key_caches };
self.cached_glyph_dimensions = cached.glyph_dimensions;
self.cached_images = cached.images;
self.cached_render_tasks = cached.render_tasks;
self.texture_cache = cached.textures;
}
None => {
@ -1357,15 +1351,13 @@ impl ResourceCache {
self.cached_glyphs.clear();
self.cached_glyph_dimensions.clear();
self.cached_images.clear();
self.cached_render_tasks.clear();
let max_texture_size = self.texture_cache.max_texture_size();
self.texture_cache = TextureCache::new(max_texture_size);
}
}
self.state = State::Idle;
self.glyph_rasterizer.reset();
self.pending_image_requests.clear();
let res = &mut self.resources;
res.font_templates.clear();
*res.font_instances.write().unwrap() = resources.font_instances;

View File

@ -53,7 +53,8 @@ impl SceneProperties {
.get(&key.id)
.cloned()
.unwrap_or_else(|| {
warn!("Property binding {:?} has an invalid value.", key);
warn!("Property binding has an invalid value.");
debug!("key={:?}", key);
LayoutTransform::identity()
})
}
@ -73,7 +74,8 @@ impl SceneProperties {
.get(&key.id)
.cloned()
.unwrap_or_else(|| {
warn!("Property binding {:?} has an invalid value.", key);
warn!("Property binding has an invalid value.");
debug!("key={:?}", key);
default_value
})
}

View File

@ -199,7 +199,7 @@ impl<T: RenderTarget> RenderTargetList<T> {
None => {
let mut new_target = T::new(Some(self.max_size), self.screen_size);
let origin = new_target.allocate(alloc_size).expect(&format!(
"Each render task must allocate <= size of one target! ({:?})",
"Each render task must allocate <= size of one target! ({})",
alloc_size
));
self.targets.push(new_target);

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use {BuiltDisplayList, BuiltDisplayListDescriptor, ClipId, ColorF, DeviceIntPoint, DeviceUintRect};
use {DeviceUintSize, FontInstanceKey, FontInstanceOptions};
use {DeviceUintSize, ExternalScrollId, FontInstanceKey, FontInstanceOptions};
use {FontInstancePlatformOptions, FontKey, FontVariation, GlyphDimensions, GlyphKey, ImageData};
use {ImageDescriptor, ImageKey, ItemTag, LayoutPoint, LayoutSize, LayoutTransform, LayoutVector2D};
use {NativeFontHandle, WorldPoint};
@ -254,7 +254,7 @@ impl Transaction {
pub fn scroll_node_with_id(
&mut self,
origin: LayoutPoint,
id: ClipId,
id: IdType,
clamp: ScrollClamping,
) {
self.ops.push(DocumentMsg::ScrollNodeWithId(origin, id, clamp));
@ -384,13 +384,19 @@ pub enum DocumentMsg {
device_pixel_ratio: f32,
},
Scroll(ScrollLocation, WorldPoint, ScrollEventPhase),
ScrollNodeWithId(LayoutPoint, ClipId, ScrollClamping),
ScrollNodeWithId(LayoutPoint, IdType, ScrollClamping),
TickScrollingBounce,
GetScrollNodeState(MsgSender<Vec<ScrollLayerState>>),
GetScrollNodeState(MsgSender<Vec<ScrollNodeState>>),
GenerateFrame,
UpdateDynamicProperties(DynamicProperties),
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum IdType {
ExternalScrollId(ExternalScrollId),
ClipId(ClipId),
}
impl fmt::Debug for DocumentMsg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
@ -425,6 +431,17 @@ bitflags!{
}
}
bitflags!{
/// Mask for clearing caches in debug commands.
#[derive(Deserialize, Serialize)]
pub struct ClearCache: u8 {
const IMAGES = 0x1;
const GLYPHS = 0x2;
const GLYPH_DIMENSIONS = 0x4;
const RENDER_TASKS = 0x8;
}
}
/// Information about a loaded capture of each document
/// that is returned by `RenderBackend`.
#[derive(Clone, Debug, Deserialize, Serialize)]
@ -448,6 +465,8 @@ pub enum DebugCommand {
EnableGpuTimeQueries(bool),
/// Display GPU overdraw results
EnableGpuSampleQueries(bool),
/// Configure if dual-source blending is used, if available.
EnableDualSourceBlending(bool),
/// Fetch current documents and display lists.
FetchDocuments,
/// Fetch current passes and batches.
@ -462,8 +481,10 @@ pub enum DebugCommand {
SaveCapture(PathBuf, CaptureBits),
/// Load a capture of all the documents state.
LoadCapture(PathBuf, MsgSender<CapturedDocument>),
/// Configure if dual-source blending is used, if available.
EnableDualSourceBlending(bool),
/// Clear cached resources, forcing them to be re-uploaded from templates.
ClearCaches(ClearCache),
/// Invalidate GPU cache, forcing the update from the CPU mirror.
InvalidateGpuCache,
}
#[derive(Clone, Deserialize, Serialize)]
@ -798,7 +819,7 @@ impl RenderApi {
);
}
pub fn get_scroll_node_state(&self, document_id: DocumentId) -> Vec<ScrollLayerState> {
pub fn get_scroll_node_state(&self, document_id: DocumentId) -> Vec<ScrollNodeState> {
let (tx, rx) = channel::msg_channel().unwrap();
self.send(document_id, DocumentMsg::GetScrollNodeState(tx));
rx.recv().unwrap()
@ -848,8 +869,8 @@ pub enum ScrollEventPhase {
}
#[derive(Clone, Deserialize, Serialize)]
pub struct ScrollLayerState {
pub id: ClipId,
pub struct ScrollNodeState {
pub id: ExternalScrollId,
pub scroll_offset: LayoutVector2D,
}

View File

@ -214,6 +214,7 @@ pub enum ScrollSensitivity {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ScrollFrameDisplayItem {
pub id: ClipId,
pub external_id: Option<ExternalScrollId>,
pub image_mask: Option<ImageMask>,
pub scroll_sensitivity: ScrollSensitivity,
}
@ -751,7 +752,6 @@ pub struct ClipChainId(pub u64, pub PipelineId);
pub enum ClipId {
Clip(u64, PipelineId),
ClipChain(ClipChainId),
ClipExternalId(u64, PipelineId),
DynamicallyAddedNode(u64, PipelineId),
}
@ -764,32 +764,14 @@ impl ClipId {
ClipId::DynamicallyAddedNode(0, pipeline_id)
}
pub fn new(id: u64, pipeline_id: PipelineId) -> ClipId {
// We do this because it is very easy to create accidentally create something that
// seems like a root scroll node, but isn't one.
if id == 0 {
return ClipId::root_scroll_node(pipeline_id);
}
ClipId::ClipExternalId(id, pipeline_id)
}
pub fn pipeline_id(&self) -> PipelineId {
match *self {
ClipId::Clip(_, pipeline_id) |
ClipId::ClipChain(ClipChainId(_, pipeline_id)) |
ClipId::ClipExternalId(_, pipeline_id) |
ClipId::DynamicallyAddedNode(_, pipeline_id) => pipeline_id,
}
}
pub fn external_id(&self) -> Option<u64> {
match *self {
ClipId::ClipExternalId(id, _) => Some(id),
_ => None,
}
}
pub fn is_root_scroll_node(&self) -> bool {
match *self {
ClipId::Clip(0, _) => true,
@ -797,3 +779,23 @@ impl ClipId {
}
}
}
/// An external identifier that uniquely identifies a scroll frame independent of its ClipId, which
/// may change from frame to frame. This should be unique within a pipeline. WebRender makes no
/// attempt to ensure uniqueness. The zero value is reserved for use by the root scroll node of
/// every pipeline, which always has an external id.
///
/// When setting display lists with the `preserve_frame_state` this id is used to preserve scroll
/// offsets between different sets of ClipScrollNodes which are ScrollFrames.
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ExternalScrollId(pub u64, pub PipelineId);
impl ExternalScrollId {
pub fn pipeline_id(&self) -> PipelineId {
self.1
}
pub fn is_root(&self) -> bool {
self.0 == 0
}
}

View File

@ -4,10 +4,10 @@
use {AlphaType, BorderDetails, BorderDisplayItem, BorderRadius, BorderWidths, BoxShadowClipMode};
use {BoxShadowDisplayItem, ClipAndScrollInfo, ClipChainId, ClipChainItem, ClipDisplayItem, ClipId};
use {ColorF, ComplexClipRegion, DisplayItem, ExtendMode, FilterOp, FontInstanceKey, GlyphInstance};
use {GlyphOptions, Gradient, GradientDisplayItem, GradientStop, IframeDisplayItem};
use {ImageDisplayItem, ImageKey, ImageMask, ImageRendering, LayerPrimitiveInfo, LayoutPoint};
use {LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
use {ColorF, ComplexClipRegion, DisplayItem, ExtendMode, ExternalScrollId, FilterOp};
use {FontInstanceKey, GlyphInstance, GlyphOptions, Gradient, GradientDisplayItem, GradientStop};
use {IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask, ImageRendering, LayerPrimitiveInfo};
use {LayoutPoint, LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
use {LineDisplayItem, LineOrientation, LineStyle, LocalClip, MixBlendMode, PipelineId};
use {PropertyBinding, PushStackingContextDisplayItem, RadialGradient, RadialGradientDisplayItem};
use {RectangleDisplayItem, ScrollFrameDisplayItem, ScrollPolicy, ScrollSensitivity, Shadow};
@ -192,7 +192,8 @@ impl<'a> BuiltDisplayListIter<'a> {
cur_item: DisplayItem {
// Dummy data, will be overwritten by `next`
item: SpecificDisplayItem::PopStackingContext,
clip_and_scroll: ClipAndScrollInfo::simple(ClipId::new(0, PipelineId::dummy())),
clip_and_scroll:
ClipAndScrollInfo::simple(ClipId::root_scroll_node(PipelineId::dummy())),
info: LayoutPrimitiveInfo::new(LayoutRect::zero()),
},
cur_stops: ItemRange::default(),
@ -1337,11 +1338,9 @@ impl DisplayListBuilder {
self.push_iter(stops);
}
fn generate_clip_id(&mut self, id: Option<ClipId>) -> ClipId {
id.unwrap_or_else(|| {
fn generate_clip_id(&mut self) -> ClipId {
self.next_clip_id += 1;
ClipId::Clip(self.next_clip_id - 1, self.pipeline_id)
})
}
fn generate_clip_chain_id(&mut self) -> ClipChainId {
@ -1351,7 +1350,7 @@ impl DisplayListBuilder {
pub fn define_scroll_frame<I>(
&mut self,
id: Option<ClipId>,
external_id: Option<ExternalScrollId>,
content_rect: LayoutRect,
clip_rect: LayoutRect,
complex_clips: I,
@ -1364,8 +1363,8 @@ impl DisplayListBuilder {
{
let parent = self.clip_stack.last().unwrap().scroll_node_id;
self.define_scroll_frame_with_parent(
id,
parent,
external_id,
content_rect,
clip_rect,
complex_clips,
@ -1375,8 +1374,8 @@ impl DisplayListBuilder {
pub fn define_scroll_frame_with_parent<I>(
&mut self,
id: Option<ClipId>,
parent: ClipId,
external_id: Option<ExternalScrollId>,
content_rect: LayoutRect,
clip_rect: LayoutRect,
complex_clips: I,
@ -1387,9 +1386,10 @@ impl DisplayListBuilder {
I: IntoIterator<Item = ComplexClipRegion>,
I::IntoIter: ExactSizeIterator + Clone,
{
let id = self.generate_clip_id(id);
let id = self.generate_clip_id();
let item = SpecificDisplayItem::ScrollFrame(ScrollFrameDisplayItem {
id,
external_id,
image_mask,
scroll_sensitivity,
});
@ -1418,7 +1418,6 @@ impl DisplayListBuilder {
pub fn define_clip<I>(
&mut self,
id: Option<ClipId>,
clip_rect: LayoutRect,
complex_clips: I,
image_mask: Option<ImageMask>,
@ -1429,16 +1428,15 @@ impl DisplayListBuilder {
{
let parent = self.clip_stack.last().unwrap().scroll_node_id;
self.define_clip_with_parent(
id,
parent,
clip_rect,
complex_clips,
image_mask)
image_mask
)
}
pub fn define_clip_with_parent<I>(
&mut self,
id: Option<ClipId>,
parent: ClipId,
clip_rect: LayoutRect,
complex_clips: I,
@ -1448,7 +1446,7 @@ impl DisplayListBuilder {
I: IntoIterator<Item = ComplexClipRegion>,
I::IntoIter: ExactSizeIterator + Clone,
{
let id = self.generate_clip_id(id);
let id = self.generate_clip_id();
let item = SpecificDisplayItem::Clip(ClipDisplayItem {
id,
image_mask: image_mask,
@ -1464,7 +1462,6 @@ impl DisplayListBuilder {
pub fn define_sticky_frame(
&mut self,
id: Option<ClipId>,
frame_rect: LayoutRect,
margins: SideOffsets2D<Option<f32>>,
vertical_offset_bounds: StickyOffsetBounds,
@ -1472,7 +1469,7 @@ impl DisplayListBuilder {
previously_applied_offset: LayoutVector2D,
) -> ClipId {
let id = self.generate_clip_id(id);
let id = self.generate_clip_id();
let item = SpecificDisplayItem::StickyFrame(StickyFrameDisplayItem {
id,
margins,

View File

@ -1 +1 @@
b6e69a8efbcd8dc3e0c0a8a9925e6a9355635de3
e772c3cb8ea0a35e6477e9dc8dd2144e2de87b56

View File

@ -431,16 +431,22 @@ impl<'a> RawtestHarness<'a> {
let mut do_test = |should_try_and_fail| {
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let clip = builder.define_clip(None, rect(110., 120., 200., 200.),
None::<ComplexClipRegion>, None);
let clip = builder.define_clip(
rect(110., 120., 200., 200.),
None::<ComplexClipRegion>,
None
);
builder.push_clip_id(clip);
builder.push_rect(&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
ColorF::new(0.0, 0.0, 1.0, 1.0));
if should_try_and_fail {
builder.save();
let clip = builder.define_clip(None, rect(80., 80., 90., 90.),
None::<ComplexClipRegion>, None);
let clip = builder.define_clip(
rect(80., 80., 90., 90.),
None::<ComplexClipRegion>,
None
);
builder.push_clip_id(clip);
builder.push_rect(&PrimitiveInfo::new(rect(110., 110., 50., 50.)),
ColorF::new(0.0, 1.0, 0.0, 1.0));
@ -458,8 +464,11 @@ impl<'a> RawtestHarness<'a> {
{
builder.save();
let clip = builder.define_clip(None, rect(80., 80., 100., 100.),
None::<ComplexClipRegion>, None);
let clip = builder.define_clip(
rect(80., 80., 100., 100.),
None::<ComplexClipRegion>,
None
);
builder.push_clip_id(clip);
builder.push_rect(&PrimitiveInfo::new(rect(150., 150., 100., 100.)),
ColorF::new(0.0, 0.0, 1.0, 1.0));

View File

@ -524,7 +524,7 @@ impl Wrench {
for (id, offset) in scroll_offsets {
txn.scroll_node_with_id(
*offset,
*id,
IdType::ClipId(*id),
ScrollClamping::NoClamping,
);
}

View File

@ -1273,11 +1273,13 @@ impl YamlFrameReader {
let content_rect = LayerRect::new(clip_rect.origin, content_size);
let numeric_id = yaml["id"].as_i64().map(|id| id as u64);
let complex_clips = self.to_complex_clip_regions(&yaml["complex"]);
let image_mask = self.to_image_mask(&yaml["image-mask"], wrench);
let external_id = numeric_id.map(|id| ExternalScrollId(id as u64, dl.pipeline_id));
let real_id = dl.define_scroll_frame(
None,
external_id,
content_rect,
clip_rect,
complex_clips,
@ -1309,7 +1311,6 @@ impl YamlFrameReader {
let numeric_id = yaml["id"].as_i64().map(|id| id as u64);
let real_id = dl.define_sticky_frame(
None,
bounds,
SideOffsets2D::new(
yaml["margin-top"].as_f32(),
@ -1389,7 +1390,7 @@ impl YamlFrameReader {
let complex_clips = self.to_complex_clip_regions(&yaml["complex"]);
let image_mask = self.to_image_mask(&yaml["image-mask"], wrench);
let real_id = dl.define_clip(None, clip_rect, complex_clips, image_mask);
let real_id = dl.define_clip(clip_rect, complex_clips, image_mask);
if let Some(numeric_id) = numeric_id {
self.clip_id_map.insert(numeric_id as u64, real_id);
}