mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1434288 - Update webrender to commit e772c3cb8ea0a35e6477e9dc8dd2144e2de87b56. r=jrmuizel
MozReview-Commit-ID: 4VM5EAtkjNt --HG-- extra : rebase_source : 5c1b5da5a99fe9405f9810030b8e3422ac82e519
This commit is contained in:
parent
b1adc0e137
commit
e8fb82d672
@ -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
|
||||
|
@ -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));
|
||||
|
@ -90,7 +90,7 @@ fn render_blob(
|
||||
}
|
||||
_ => {
|
||||
return Err(api::BlobImageError::Other(
|
||||
format!("Usupported image format {:?}", descriptor.format),
|
||||
format!("Usupported image format"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,14 +270,11 @@ 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) {
|
||||
return node.set_scroll_origin(&origin, clamp);
|
||||
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));
|
||||
@ -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) {
|
||||
node.apply_old_scrolling_state(scrolling_state);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 { .. } => {
|
||||
Some(&prim_run_context.scroll_node.world_content_transform)
|
||||
},
|
||||
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,
|
||||
) {
|
||||
|
@ -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));
|
||||
|
@ -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(),
|
||||
}
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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,18 +930,19 @@ 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.
|
||||
self.cached_images.clear();
|
||||
self.cached_glyphs.clear();
|
||||
self.cached_render_tasks.clear();
|
||||
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) {
|
||||
@ -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;
|
||||
|
@ -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
|
||||
})
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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(|| {
|
||||
self.next_clip_id += 1;
|
||||
ClipId::Clip(self.next_clip_id - 1, self.pipeline_id)
|
||||
})
|
||||
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,
|
||||
|
@ -1 +1 @@
|
||||
b6e69a8efbcd8dc3e0c0a8a9925e6a9355635de3
|
||||
e772c3cb8ea0a35e6477e9dc8dd2144e2de87b56
|
||||
|
@ -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));
|
||||
|
@ -524,7 +524,7 @@ impl Wrench {
|
||||
for (id, offset) in scroll_offsets {
|
||||
txn.scroll_node_with_id(
|
||||
*offset,
|
||||
*id,
|
||||
IdType::ClipId(*id),
|
||||
ScrollClamping::NoClamping,
|
||||
);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user