Backed out changeset 1d332a5ff4f9 (bug 1724846) for causing Bug 1727715.
CLOSED TREE
This commit is contained in:
@@ -465,7 +465,7 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline(
|
||||
aSceneBuilderTxn.SetDisplayList(gfx::DeviceColor(0.f, 0.f, 0.f, 0.f), aEpoch,
|
||||
wr::ToLayoutSize(aPipeline->mScBounds.Size()),
|
||||
aPipelineId, dl.dl_desc, dl.dl_items,
|
||||
dl.dl_cache, dl.dl_spatial_tree);
|
||||
dl.dl_cache);
|
||||
}
|
||||
|
||||
void AsyncImagePipelineManager::ApplyAsyncImageForPipeline(
|
||||
@@ -520,7 +520,7 @@ void AsyncImagePipelineManager::SetEmptyDisplayList(
|
||||
builder.Finalize(dl);
|
||||
txn.SetDisplayList(gfx::DeviceColor(0.f, 0.f, 0.f, 0.f), epoch,
|
||||
wr::ToLayoutSize(pipeline->mScBounds.Size()), aPipelineId,
|
||||
dl.dl_desc, dl.dl_items, dl.dl_cache, dl.dl_spatial_tree);
|
||||
dl.dl_desc, dl.dl_items, dl.dl_cache);
|
||||
}
|
||||
|
||||
void AsyncImagePipelineManager::HoldExternalImage(
|
||||
|
||||
@@ -18,7 +18,6 @@ void IPDLParamTraits<mozilla::layers::DisplayListData>::Write(
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mCommands);
|
||||
WriteIPDLParam(aMsg, aActor, std::move(aParam.mDLItems));
|
||||
WriteIPDLParam(aMsg, aActor, std::move(aParam.mDLCache));
|
||||
WriteIPDLParam(aMsg, aActor, std::move(aParam.mDLSpatialTree));
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mDLDesc);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mRemotePipelineIds);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mResourceUpdates);
|
||||
@@ -35,7 +34,6 @@ bool IPDLParamTraits<mozilla::layers::DisplayListData>::Read(
|
||||
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mCommands) &&
|
||||
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDLItems) &&
|
||||
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDLCache) &&
|
||||
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDLSpatialTree) &&
|
||||
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDLDesc) &&
|
||||
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRemotePipelineIds) &&
|
||||
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mResourceUpdates) &&
|
||||
|
||||
@@ -22,7 +22,6 @@ struct DisplayListData {
|
||||
nsTArray<WebRenderParentCommand> mCommands;
|
||||
Maybe<mozilla::ipc::ByteBuf> mDLItems;
|
||||
Maybe<mozilla::ipc::ByteBuf> mDLCache;
|
||||
Maybe<mozilla::ipc::ByteBuf> mDLSpatialTree;
|
||||
wr::BuiltDisplayListDescriptor mDLDesc;
|
||||
nsTArray<wr::PipelineId> mRemotePipelineIds;
|
||||
nsTArray<OpUpdateResource> mResourceUpdates;
|
||||
|
||||
@@ -1101,8 +1101,7 @@ void WebRenderBridgeParent::SetAPZSampleTime() {
|
||||
|
||||
bool WebRenderBridgeParent::SetDisplayList(
|
||||
const LayoutDeviceRect& aRect, ipc::ByteBuf&& aDLItems,
|
||||
ipc::ByteBuf&& aDLCache, ipc::ByteBuf&& aSpatialTreeDL,
|
||||
const wr::BuiltDisplayListDescriptor& aDLDesc,
|
||||
ipc::ByteBuf&& aDLCache, const wr::BuiltDisplayListDescriptor& aDLDesc,
|
||||
const nsTArray<OpUpdateResource>& aResourceUpdates,
|
||||
const nsTArray<RefCountedShmem>& aSmallShmems,
|
||||
const nsTArray<ipc::Shmem>& aLargeShmems, const TimeStamp& aTxnStartTime,
|
||||
@@ -1115,7 +1114,6 @@ bool WebRenderBridgeParent::SetDisplayList(
|
||||
|
||||
wr::Vec<uint8_t> dlItems(std::move(aDLItems));
|
||||
wr::Vec<uint8_t> dlCache(std::move(aDLCache));
|
||||
wr::Vec<uint8_t> dlSpatialTreeData(std::move(aSpatialTreeDL));
|
||||
|
||||
if (IsRootWebRenderBridgeParent()) {
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
@@ -1131,7 +1129,7 @@ bool WebRenderBridgeParent::SetDisplayList(
|
||||
gfx::DeviceColor clearColor(0.f, 0.f, 0.f, 0.f);
|
||||
aTxn.SetDisplayList(clearColor, aWrEpoch,
|
||||
wr::ToLayoutSize(RoundedToInt(aRect).Size()), mPipelineId,
|
||||
aDLDesc, dlItems, dlCache, dlSpatialTreeData);
|
||||
aDLDesc, dlItems, dlCache);
|
||||
|
||||
if (aObserveLayersUpdate) {
|
||||
aTxn.Notify(
|
||||
@@ -1177,12 +1175,10 @@ bool WebRenderBridgeParent::ProcessDisplayListData(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aDisplayList.mDLItems && aDisplayList.mDLCache &&
|
||||
aDisplayList.mDLSpatialTree && aValidTransaction &&
|
||||
if (aDisplayList.mDLItems && aDisplayList.mDLCache && aValidTransaction &&
|
||||
!SetDisplayList(aDisplayList.mRect,
|
||||
std::move(aDisplayList.mDLItems.ref()),
|
||||
std::move(aDisplayList.mDLCache.ref()),
|
||||
std::move(aDisplayList.mDLSpatialTree.ref()),
|
||||
aDisplayList.mDLDesc, aDisplayList.mResourceUpdates,
|
||||
aDisplayList.mSmallShmems, aDisplayList.mLargeShmems,
|
||||
aTxnStartTime, txn, aWrEpoch, aObserveLayersUpdate)) {
|
||||
|
||||
@@ -332,7 +332,7 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
|
||||
bool aObserveLayersUpdate);
|
||||
|
||||
bool SetDisplayList(const LayoutDeviceRect& aRect, ipc::ByteBuf&& aDLItems,
|
||||
ipc::ByteBuf&& aDLCache, ipc::ByteBuf&& aSpatialTreeDL,
|
||||
ipc::ByteBuf&& aDLCache,
|
||||
const wr::BuiltDisplayListDescriptor& aDLDesc,
|
||||
const nsTArray<OpUpdateResource>& aResourceUpdates,
|
||||
const nsTArray<RefCountedShmem>& aSmallShmems,
|
||||
|
||||
@@ -461,7 +461,6 @@ void WebRenderLayerManager::EndTransactionWithoutLayer(
|
||||
builder.Finalize(dlData);
|
||||
mLastDisplayListSize.items_size = dlData.mDLItems->mCapacity;
|
||||
mLastDisplayListSize.cache_size = dlData.mDLCache->mCapacity;
|
||||
mLastDisplayListSize.spatial_tree_size = dlData.mDLSpatialTree->mCapacity;
|
||||
resourceUpdates.Flush(dlData.mResourceUpdates, dlData.mSmallShmems,
|
||||
dlData.mLargeShmems);
|
||||
dlData.mRect =
|
||||
|
||||
@@ -263,12 +263,10 @@ void TransactionBuilder::SetDisplayList(
|
||||
const gfx::DeviceColor& aBgColor, Epoch aEpoch,
|
||||
const wr::LayoutSize& aViewportSize, wr::WrPipelineId pipeline_id,
|
||||
wr::BuiltDisplayListDescriptor dl_descriptor,
|
||||
wr::Vec<uint8_t>& dl_items_data, wr::Vec<uint8_t>& dl_cache_data,
|
||||
wr::Vec<uint8_t>& dl_spatial_tree) {
|
||||
wr::Vec<uint8_t>& dl_items_data, wr::Vec<uint8_t>& dl_cache_data) {
|
||||
wr_transaction_set_display_list(mTxn, aEpoch, ToColorF(aBgColor),
|
||||
aViewportSize, pipeline_id, dl_descriptor,
|
||||
&dl_items_data.inner, &dl_cache_data.inner,
|
||||
&dl_spatial_tree.inner);
|
||||
&dl_items_data.inner, &dl_cache_data.inner);
|
||||
}
|
||||
|
||||
void TransactionBuilder::ClearDisplayList(Epoch aEpoch,
|
||||
@@ -998,9 +996,9 @@ void DisplayListBuilder::DumpSerializedDisplayList() {
|
||||
}
|
||||
|
||||
void DisplayListBuilder::Finalize(BuiltDisplayList& aOutDisplayList) {
|
||||
wr_api_finalize_builder(
|
||||
mWrState, &aOutDisplayList.dl_desc, &aOutDisplayList.dl_items.inner,
|
||||
&aOutDisplayList.dl_cache.inner, &aOutDisplayList.dl_spatial_tree.inner);
|
||||
wr_api_finalize_builder(mWrState, &aOutDisplayList.dl_desc,
|
||||
&aOutDisplayList.dl_items.inner,
|
||||
&aOutDisplayList.dl_cache.inner);
|
||||
}
|
||||
|
||||
void DisplayListBuilder::Finalize(layers::DisplayListData& aOutTransaction) {
|
||||
@@ -1008,23 +1006,18 @@ void DisplayListBuilder::Finalize(layers::DisplayListData& aOutTransaction) {
|
||||
wr_dp_set_cache_size(mWrState, mDisplayItemCache->CurrentSize());
|
||||
}
|
||||
|
||||
wr::VecU8 dlItems, dlCache, dlSpatialTree;
|
||||
wr::VecU8 dlItems, dlCache;
|
||||
wr_api_finalize_builder(mWrState, &aOutTransaction.mDLDesc, &dlItems.inner,
|
||||
&dlCache.inner, &dlSpatialTree.inner);
|
||||
&dlCache.inner);
|
||||
aOutTransaction.mDLItems.emplace(dlItems.inner.data, dlItems.inner.length,
|
||||
dlItems.inner.capacity);
|
||||
aOutTransaction.mDLCache.emplace(dlCache.inner.data, dlCache.inner.length,
|
||||
dlCache.inner.capacity);
|
||||
aOutTransaction.mDLSpatialTree.emplace(dlSpatialTree.inner.data,
|
||||
dlSpatialTree.inner.length,
|
||||
dlSpatialTree.inner.capacity);
|
||||
aOutTransaction.mRemotePipelineIds = std::move(mRemotePipelineIds);
|
||||
dlItems.inner.capacity = 0;
|
||||
dlItems.inner.data = nullptr;
|
||||
dlCache.inner.capacity = 0;
|
||||
dlCache.inner.data = nullptr;
|
||||
dlSpatialTree.inner.capacity = 0;
|
||||
dlSpatialTree.inner.data = nullptr;
|
||||
}
|
||||
|
||||
Maybe<wr::WrSpatialId> DisplayListBuilder::PushStackingContext(
|
||||
|
||||
@@ -113,8 +113,7 @@ class TransactionBuilder final {
|
||||
wr::WrPipelineId pipeline_id,
|
||||
wr::BuiltDisplayListDescriptor dl_descriptor,
|
||||
wr::Vec<uint8_t>& dl_items_data,
|
||||
wr::Vec<uint8_t>& dl_cache_data,
|
||||
wr::Vec<uint8_t>& dl_spatial_tree);
|
||||
wr::Vec<uint8_t>& dl_cache_data);
|
||||
|
||||
void ClearDisplayList(Epoch aEpoch, wr::WrPipelineId aPipeline);
|
||||
|
||||
|
||||
@@ -740,7 +740,6 @@ struct ByteBuffer {
|
||||
struct BuiltDisplayList {
|
||||
wr::VecU8 dl_items;
|
||||
wr::VecU8 dl_cache;
|
||||
wr::VecU8 dl_spatial_tree;
|
||||
wr::BuiltDisplayListDescriptor dl_desc;
|
||||
};
|
||||
|
||||
|
||||
@@ -1842,7 +1842,6 @@ pub extern "C" fn wr_transaction_set_display_list(
|
||||
dl_descriptor: BuiltDisplayListDescriptor,
|
||||
dl_items_data: &mut WrVecU8,
|
||||
dl_cache_data: &mut WrVecU8,
|
||||
dl_spatial_tree_data: &mut WrVecU8,
|
||||
) {
|
||||
let color = if background.a == 0.0 { None } else { Some(background) };
|
||||
|
||||
@@ -1854,7 +1853,6 @@ pub extern "C" fn wr_transaction_set_display_list(
|
||||
let payload = DisplayListPayload {
|
||||
items_data: dl_items_data.flush_into_vec(),
|
||||
cache_data: dl_cache_data.flush_into_vec(),
|
||||
spatial_tree: dl_spatial_tree_data.flush_into_vec(),
|
||||
};
|
||||
|
||||
let dl = BuiltDisplayList::from_data(payload, dl_descriptor);
|
||||
@@ -3776,14 +3774,12 @@ pub unsafe extern "C" fn wr_api_finalize_builder(
|
||||
dl_descriptor: &mut BuiltDisplayListDescriptor,
|
||||
dl_items_data: &mut WrVecU8,
|
||||
dl_cache_data: &mut WrVecU8,
|
||||
dl_spatial_tree: &mut WrVecU8,
|
||||
) {
|
||||
let frame_builder = mem::replace(&mut state.frame_builder, WebRenderFrameBuilder::new(state.pipeline_id));
|
||||
let (_, dl) = frame_builder.dl_builder.finalize();
|
||||
let (payload, descriptor) = dl.into_data();
|
||||
*dl_items_data = WrVecU8::from_vec(payload.items_data);
|
||||
*dl_cache_data = WrVecU8::from_vec(payload.cache_data);
|
||||
*dl_spatial_tree = WrVecU8::from_vec(payload.spatial_tree);
|
||||
*dl_descriptor = descriptor;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,16 +35,16 @@
|
||||
//! - backdrop filters (see add_backdrop_filter)
|
||||
//!
|
||||
|
||||
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, BuiltDisplayList, PrimitiveFlags};
|
||||
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, PrimitiveFlags};
|
||||
use api::{ClipId, ColorF, CommonItemProperties, ComplexClipRegion, ComponentTransferFuncType, RasterSpace};
|
||||
use api::{DisplayItem, DisplayItemRef, ExtendMode, ExternalScrollId, FilterData, SharedFontInstanceMap};
|
||||
use api::{FilterOp, FilterPrimitive, FontInstanceKey, FontSize, GlyphInstance, GlyphOptions, GradientStop};
|
||||
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, ColorDepth, QualitySettings};
|
||||
use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId, MixBlendMode, StackingContextFlags};
|
||||
use api::{PropertyBinding, ReferenceFrameKind, ScrollFrameDescriptor, ScrollSensitivity, ReferenceFrameMapper};
|
||||
use api::{Shadow, SpaceAndClipInfo, SpatialId, StickyFrameDescriptor, ImageMask, ItemTag};
|
||||
use api::{PropertyBinding, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity};
|
||||
use api::{Shadow, SpaceAndClipInfo, SpatialId, StickyFrameDisplayItem, ImageMask, ItemTag};
|
||||
use api::{ClipMode, PrimitiveKeyKind, TransformStyle, YuvColorSpace, ColorRange, YuvData, TempFilterData};
|
||||
use api::{ReferenceTransformBinding, Rotation, FillRule, SpatialTreeItem, ReferenceFrameDescriptor};
|
||||
use api::{ReferenceTransformBinding, Rotation, FillRule};
|
||||
use api::units::*;
|
||||
use crate::image_tiling::simplify_repeated_primitive;
|
||||
use crate::clip::{ClipChainId, ClipItemKey, ClipStore, ClipItemKeyKind};
|
||||
@@ -89,6 +89,78 @@ use crate::util::{MaxRect, VecHelper};
|
||||
use crate::filterdata::{SFilterDataComponent, SFilterData, SFilterDataKey};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
/// The offset stack for a given reference frame.
|
||||
struct ReferenceFrameState {
|
||||
/// A stack of current offsets from the current reference frame scope.
|
||||
offsets: Vec<LayoutVector2D>,
|
||||
}
|
||||
|
||||
/// Maps from stacking context layout coordinates into reference frame
|
||||
/// relative coordinates.
|
||||
struct ReferenceFrameMapper {
|
||||
/// A stack of reference frame scopes.
|
||||
frames: Vec<ReferenceFrameState>,
|
||||
}
|
||||
|
||||
impl ReferenceFrameMapper {
|
||||
fn new() -> Self {
|
||||
ReferenceFrameMapper {
|
||||
frames: vec![
|
||||
ReferenceFrameState {
|
||||
offsets: vec![
|
||||
LayoutVector2D::zero(),
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/// Push a new scope. This resets the current offset to zero, and is
|
||||
/// used when a new reference frame or iframe is pushed.
|
||||
fn push_scope(&mut self) {
|
||||
self.frames.push(ReferenceFrameState {
|
||||
offsets: vec![
|
||||
LayoutVector2D::zero(),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/// Pop a reference frame scope off the stack.
|
||||
fn pop_scope(&mut self) {
|
||||
self.frames.pop().unwrap();
|
||||
}
|
||||
|
||||
/// Push a new offset for the current scope. This is used when
|
||||
/// a new stacking context is pushed.
|
||||
fn push_offset(&mut self, offset: LayoutVector2D) {
|
||||
let frame = self.frames.last_mut().unwrap();
|
||||
let current_offset = *frame.offsets.last().unwrap();
|
||||
frame.offsets.push(current_offset + offset);
|
||||
}
|
||||
|
||||
/// Pop a local stacking context offset from the current scope.
|
||||
fn pop_offset(&mut self) {
|
||||
let frame = self.frames.last_mut().unwrap();
|
||||
frame.offsets.pop().unwrap();
|
||||
}
|
||||
|
||||
/// Retrieve the current offset to allow converting a stacking context
|
||||
/// relative coordinate to be relative to the owing reference frame.
|
||||
/// TODO(gw): We could perhaps have separate coordinate spaces for this,
|
||||
/// however that's going to either mean a lot of changes to
|
||||
/// public API code, or a lot of changes to internal code.
|
||||
/// Before doing that, we should revisit how Gecko would
|
||||
/// prefer to provide coordinates.
|
||||
/// TODO(gw): For now, this includes only the reference frame relative
|
||||
/// offset. Soon, we will expand this to include the initial
|
||||
/// scroll offsets that are now available on scroll nodes. This
|
||||
/// will allow normalizing the coordinates even between display
|
||||
/// lists where APZ has scrolled the content.
|
||||
fn current_offset(&self) -> LayoutVector2D {
|
||||
*self.frames.last().unwrap().offsets.last().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Offsets primitives (and clips) by the external scroll offset
|
||||
/// supplied to scroll nodes.
|
||||
pub struct ScrollOffsetMapper {
|
||||
@@ -560,43 +632,6 @@ impl<'a> SceneBuilder<'a> {
|
||||
rf_offset + scroll_offset
|
||||
}
|
||||
|
||||
fn build_spatial_tree_for_display_list(
|
||||
&mut self,
|
||||
dl: &BuiltDisplayList,
|
||||
pipeline_id: PipelineId,
|
||||
) {
|
||||
dl.iter_spatial_tree(|item| {
|
||||
match item {
|
||||
SpatialTreeItem::ScrollFrame(descriptor) => {
|
||||
let parent_space = self.get_space(descriptor.parent_space);
|
||||
self.build_scroll_frame(
|
||||
descriptor,
|
||||
parent_space,
|
||||
pipeline_id,
|
||||
);
|
||||
}
|
||||
SpatialTreeItem::ReferenceFrame(descriptor) => {
|
||||
let parent_space = self.get_space(descriptor.parent_spatial_id);
|
||||
self.build_reference_frame(
|
||||
descriptor,
|
||||
parent_space,
|
||||
pipeline_id,
|
||||
);
|
||||
}
|
||||
SpatialTreeItem::StickyFrame(descriptor) => {
|
||||
let parent_space = self.get_space(descriptor.parent_spatial_id);
|
||||
self.build_sticky_frame(
|
||||
descriptor,
|
||||
parent_space,
|
||||
);
|
||||
}
|
||||
SpatialTreeItem::Invalid => {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn build_all(&mut self, root_pipeline: &ScenePipeline) {
|
||||
enum ContextKind<'a> {
|
||||
Root,
|
||||
@@ -620,10 +655,6 @@ impl<'a> SceneBuilder<'a> {
|
||||
root_pipeline.pipeline_id,
|
||||
&root_pipeline.viewport_size,
|
||||
);
|
||||
self.build_spatial_tree_for_display_list(
|
||||
&root_pipeline.display_list.display_list,
|
||||
root_pipeline.pipeline_id,
|
||||
);
|
||||
|
||||
let mut stack = vec![BuildContext {
|
||||
pipeline_id: root_pipeline.pipeline_id,
|
||||
@@ -682,9 +713,67 @@ impl<'a> SceneBuilder<'a> {
|
||||
traversal = subtraversal;
|
||||
continue 'outer;
|
||||
}
|
||||
DisplayItem::PushReferenceFrame(..) => {
|
||||
DisplayItem::PushReferenceFrame(ref info) => {
|
||||
profile_scope!("build_reference_frame");
|
||||
let parent_space = self.get_space(info.parent_spatial_id);
|
||||
let mut subtraversal = item.sub_iter();
|
||||
let current_offset = self.current_offset(parent_space);
|
||||
|
||||
let transform = match info.reference_frame.transform {
|
||||
ReferenceTransformBinding::Static { binding } => binding,
|
||||
ReferenceTransformBinding::Computed { scale_from, vertical_flip, rotation } => {
|
||||
let content_size = &self.iframe_size.last().unwrap();
|
||||
|
||||
let mut transform = if let Some(scale_from) = scale_from {
|
||||
// If we have a 90/270 degree rotation, then scale_from
|
||||
// and content_size are in different coordinate spaces and
|
||||
// we need to swap width/height for them to be correct.
|
||||
match rotation {
|
||||
Rotation::Degree0 |
|
||||
Rotation::Degree180 => {
|
||||
LayoutTransform::scale(
|
||||
content_size.width / scale_from.width,
|
||||
content_size.height / scale_from.height,
|
||||
1.0
|
||||
)
|
||||
},
|
||||
Rotation::Degree90 |
|
||||
Rotation::Degree270 => {
|
||||
LayoutTransform::scale(
|
||||
content_size.height / scale_from.width,
|
||||
content_size.width / scale_from.height,
|
||||
1.0
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LayoutTransform::identity()
|
||||
};
|
||||
|
||||
if vertical_flip {
|
||||
let content_size = &self.iframe_size.last().unwrap();
|
||||
transform = transform
|
||||
.then_translate(LayoutVector3D::new(0.0, content_size.height, 0.0))
|
||||
.pre_scale(1.0, -1.0, 1.0);
|
||||
}
|
||||
|
||||
let rotate = rotation.to_matrix(**content_size);
|
||||
let transform = transform.then(&rotate);
|
||||
|
||||
PropertyBinding::Value(transform)
|
||||
},
|
||||
};
|
||||
|
||||
self.push_reference_frame(
|
||||
info.reference_frame.id,
|
||||
Some(parent_space),
|
||||
bc.pipeline_id,
|
||||
info.reference_frame.transform_style,
|
||||
transform,
|
||||
info.reference_frame.kind,
|
||||
current_offset + info.origin.to_vector(),
|
||||
);
|
||||
|
||||
self.rf_mapper.push_scope();
|
||||
let new_context = BuildContext {
|
||||
@@ -704,11 +793,30 @@ impl<'a> SceneBuilder<'a> {
|
||||
profile_scope!("iframe");
|
||||
|
||||
let space = self.get_space(info.space_and_clip.spatial_id);
|
||||
let subtraversal = match self.push_iframe(info, space) {
|
||||
let (size, subtraversal) = match self.push_iframe(info, space) {
|
||||
Some(pair) => pair,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
// Get a clip-chain id for the root clip for this pipeline. We will
|
||||
// add that as an unconditional clip to any tile cache created within
|
||||
// this iframe. This ensures these clips are handled by the tile cache
|
||||
// compositing code, which is more efficient and accurate than applying
|
||||
// these clips individually to each primitive.
|
||||
let clip_id = ClipId::root(info.pipeline_id);
|
||||
let clip_chain_id = self.get_clip_chain(clip_id);
|
||||
|
||||
// If this is a root iframe, force a new tile cache both before and after
|
||||
// adding primitives for this iframe.
|
||||
if self.iframe_size.is_empty() {
|
||||
self.add_tile_cache_barrier_if_needed(SliceFlags::empty());
|
||||
assert!(self.root_iframe_clip.is_none());
|
||||
self.root_iframe_clip = Some(clip_chain_id);
|
||||
}
|
||||
|
||||
self.rf_mapper.push_scope();
|
||||
self.iframe_size.push(size);
|
||||
|
||||
let new_context = BuildContext {
|
||||
pipeline_id: info.pipeline_id,
|
||||
kind: ContextKind::Iframe {
|
||||
@@ -772,7 +880,7 @@ impl<'a> SceneBuilder<'a> {
|
||||
|
||||
fn build_sticky_frame(
|
||||
&mut self,
|
||||
info: &StickyFrameDescriptor,
|
||||
info: &StickyFrameDisplayItem,
|
||||
parent_node_index: SpatialNodeIndex,
|
||||
) {
|
||||
let current_offset = self.current_offset(parent_node_index);
|
||||
@@ -793,72 +901,9 @@ impl<'a> SceneBuilder<'a> {
|
||||
self.id_to_index_mapper.add_spatial_node(info.id, index);
|
||||
}
|
||||
|
||||
fn build_reference_frame(
|
||||
&mut self,
|
||||
info: &ReferenceFrameDescriptor,
|
||||
parent_space: SpatialNodeIndex,
|
||||
pipeline_id: PipelineId,
|
||||
) {
|
||||
let transform = match info.reference_frame.transform {
|
||||
ReferenceTransformBinding::Static { binding } => binding,
|
||||
ReferenceTransformBinding::Computed { scale_from, vertical_flip, rotation } => {
|
||||
let content_size = &self.iframe_size.last().unwrap();
|
||||
|
||||
let mut transform = if let Some(scale_from) = scale_from {
|
||||
// If we have a 90/270 degree rotation, then scale_from
|
||||
// and content_size are in different coordinate spaces and
|
||||
// we need to swap width/height for them to be correct.
|
||||
match rotation {
|
||||
Rotation::Degree0 |
|
||||
Rotation::Degree180 => {
|
||||
LayoutTransform::scale(
|
||||
content_size.width / scale_from.width,
|
||||
content_size.height / scale_from.height,
|
||||
1.0
|
||||
)
|
||||
},
|
||||
Rotation::Degree90 |
|
||||
Rotation::Degree270 => {
|
||||
LayoutTransform::scale(
|
||||
content_size.height / scale_from.width,
|
||||
content_size.width / scale_from.height,
|
||||
1.0
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LayoutTransform::identity()
|
||||
};
|
||||
|
||||
if vertical_flip {
|
||||
let content_size = &self.iframe_size.last().unwrap();
|
||||
transform = transform
|
||||
.then_translate(LayoutVector3D::new(0.0, content_size.height, 0.0))
|
||||
.pre_scale(1.0, -1.0, 1.0);
|
||||
}
|
||||
|
||||
let rotate = rotation.to_matrix(**content_size);
|
||||
let transform = transform.then(&rotate);
|
||||
|
||||
PropertyBinding::Value(transform)
|
||||
},
|
||||
};
|
||||
|
||||
self.push_reference_frame(
|
||||
info.reference_frame.id,
|
||||
Some(parent_space),
|
||||
pipeline_id,
|
||||
info.reference_frame.transform_style,
|
||||
transform,
|
||||
info.reference_frame.kind,
|
||||
info.origin.to_vector(),
|
||||
);
|
||||
}
|
||||
|
||||
fn build_scroll_frame(
|
||||
&mut self,
|
||||
info: &ScrollFrameDescriptor,
|
||||
info: &ScrollFrameDisplayItem,
|
||||
parent_node_index: SpatialNodeIndex,
|
||||
pipeline_id: PipelineId,
|
||||
) {
|
||||
@@ -886,7 +931,7 @@ impl<'a> SceneBuilder<'a> {
|
||||
&mut self,
|
||||
info: &IframeDisplayItem,
|
||||
spatial_node_index: SpatialNodeIndex,
|
||||
) -> Option<BuiltDisplayListIter<'a>> {
|
||||
) -> Option<(LayoutSize, BuiltDisplayListIter<'a>)> {
|
||||
let iframe_pipeline_id = info.pipeline_id;
|
||||
let pipeline = match self.scene.pipelines.get(&iframe_pipeline_id) {
|
||||
Some(pipeline) => pipeline,
|
||||
@@ -945,30 +990,7 @@ impl<'a> SceneBuilder<'a> {
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
// Get a clip-chain id for the root clip for this pipeline. We will
|
||||
// add that as an unconditional clip to any tile cache created within
|
||||
// this iframe. This ensures these clips are handled by the tile cache
|
||||
// compositing code, which is more efficient and accurate than applying
|
||||
// these clips individually to each primitive.
|
||||
let clip_id = ClipId::root(info.pipeline_id);
|
||||
let clip_chain_id = self.get_clip_chain(clip_id);
|
||||
|
||||
// If this is a root iframe, force a new tile cache both before and after
|
||||
// adding primitives for this iframe.
|
||||
if self.iframe_size.is_empty() {
|
||||
self.add_tile_cache_barrier_if_needed(SliceFlags::empty());
|
||||
assert!(self.root_iframe_clip.is_none());
|
||||
self.root_iframe_clip = Some(clip_chain_id);
|
||||
}
|
||||
self.iframe_size.push(info.bounds.size());
|
||||
self.rf_mapper.push_scope();
|
||||
|
||||
self.build_spatial_tree_for_display_list(
|
||||
&pipeline.display_list.display_list,
|
||||
iframe_pipeline_id,
|
||||
);
|
||||
|
||||
Some(pipeline.display_list.iter())
|
||||
Some((bounds.size(), pipeline.display_list.iter()))
|
||||
}
|
||||
|
||||
fn get_space(
|
||||
@@ -1512,6 +1534,25 @@ impl<'a> SceneBuilder<'a> {
|
||||
&clips,
|
||||
);
|
||||
},
|
||||
DisplayItem::ScrollFrame(ref info) => {
|
||||
profile_scope!("scrollframe");
|
||||
|
||||
let parent_space = self.get_space(info.parent_space);
|
||||
self.build_scroll_frame(
|
||||
info,
|
||||
parent_space,
|
||||
pipeline_id,
|
||||
);
|
||||
}
|
||||
DisplayItem::StickyFrame(ref info) => {
|
||||
profile_scope!("stickyframe");
|
||||
|
||||
let parent_space = self.get_space(info.parent_spatial_id);
|
||||
self.build_sticky_frame(
|
||||
info,
|
||||
parent_space,
|
||||
);
|
||||
}
|
||||
DisplayItem::BackdropFilter(ref info) => {
|
||||
profile_scope!("backdrop");
|
||||
|
||||
|
||||
@@ -115,15 +115,6 @@ impl SpaceAndClipInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, PeekPoke)]
|
||||
pub enum SpatialTreeItem {
|
||||
ScrollFrame(ScrollFrameDescriptor),
|
||||
ReferenceFrame(ReferenceFrameDescriptor),
|
||||
StickyFrame(StickyFrameDescriptor),
|
||||
Invalid,
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, PeekPoke)]
|
||||
pub enum DisplayItem {
|
||||
@@ -151,6 +142,8 @@ pub enum DisplayItem {
|
||||
ClipChain(ClipChainItem),
|
||||
|
||||
// Spaces and Frames that content can be scoped under.
|
||||
ScrollFrame(ScrollFrameDisplayItem),
|
||||
StickyFrame(StickyFrameDisplayItem),
|
||||
Iframe(IframeDisplayItem),
|
||||
PushReferenceFrame(ReferenceFrameDisplayListItem),
|
||||
PushStackingContext(PushStackingContextDisplayItem),
|
||||
@@ -199,6 +192,8 @@ pub enum DebugDisplayItem {
|
||||
RectClip(RectClipDisplayItem),
|
||||
ClipChain(ClipChainItem, Vec<ClipId>),
|
||||
|
||||
ScrollFrame(ScrollFrameDisplayItem),
|
||||
StickyFrame(StickyFrameDisplayItem),
|
||||
Iframe(IframeDisplayItem),
|
||||
PushReferenceFrame(ReferenceFrameDisplayListItem),
|
||||
PushStackingContext(PushStackingContextDisplayItem),
|
||||
@@ -265,7 +260,7 @@ impl StickyOffsetBounds {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
|
||||
pub struct StickyFrameDescriptor {
|
||||
pub struct StickyFrameDisplayItem {
|
||||
pub id: SpatialId,
|
||||
pub parent_spatial_id: SpatialId,
|
||||
pub bounds: LayoutRect,
|
||||
@@ -302,7 +297,7 @@ pub enum ScrollSensitivity {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
|
||||
pub struct ScrollFrameDescriptor {
|
||||
pub struct ScrollFrameDisplayItem {
|
||||
/// The id of the space this scroll frame creates
|
||||
pub scroll_frame_id: SpatialId,
|
||||
/// The size of the contents this contains (so the backend knows how far it can scroll).
|
||||
@@ -737,10 +732,6 @@ pub struct BackdropFilterDisplayItem {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
|
||||
pub struct ReferenceFrameDisplayListItem {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
|
||||
pub struct ReferenceFrameDescriptor {
|
||||
pub origin: LayoutPoint,
|
||||
pub parent_spatial_id: SpatialId,
|
||||
pub reference_frame: ReferenceFrame,
|
||||
@@ -1719,9 +1710,11 @@ impl DisplayItem {
|
||||
DisplayItem::SetPoints => "set_points",
|
||||
DisplayItem::RadialGradient(..) => "radial_gradient",
|
||||
DisplayItem::Rectangle(..) => "rectangle",
|
||||
DisplayItem::ScrollFrame(..) => "scroll_frame",
|
||||
DisplayItem::SetGradientStops => "set_gradient_stops",
|
||||
DisplayItem::ReuseItems(..) => "reuse_item",
|
||||
DisplayItem::RetainedItems(..) => "retained_items",
|
||||
DisplayItem::StickyFrame(..) => "sticky_frame",
|
||||
DisplayItem::Text(..) => "text",
|
||||
DisplayItem::YuvImage(..) => "yuv_image",
|
||||
DisplayItem::BackdropFilter(..) => "backdrop_filter",
|
||||
|
||||
@@ -8,7 +8,7 @@ use peek_poke::{poke_inplace_slice, poke_into_vec, Poke};
|
||||
#[cfg(feature = "deserialize")]
|
||||
use serde::de::Deserializer;
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::ser::Serializer;
|
||||
use serde::ser::{Serializer, SerializeSeq};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io::Write;
|
||||
use std::marker::PhantomData;
|
||||
@@ -114,35 +114,19 @@ pub struct DisplayListPayload {
|
||||
|
||||
/// Serde encoded DisplayItemCache structs
|
||||
pub cache_data: Vec<u8>,
|
||||
|
||||
/// Serde encoded SpatialTreeItem structs
|
||||
pub spatial_tree: Vec<u8>,
|
||||
}
|
||||
|
||||
impl DisplayListPayload {
|
||||
fn size_in_bytes(&self) -> usize {
|
||||
self.items_data.len() +
|
||||
self.cache_data.len() +
|
||||
self.spatial_tree.len()
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
fn create_debug_spatial_tree_items(&self) -> Vec<di::SpatialTreeItem> {
|
||||
let mut items = Vec::new();
|
||||
|
||||
iter_spatial_tree(&self.spatial_tree, |item| {
|
||||
items.push(*item);
|
||||
});
|
||||
|
||||
items
|
||||
self.cache_data.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl MallocSizeOf for DisplayListPayload {
|
||||
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
self.items_data.size_of(ops) +
|
||||
self.cache_data.size_of(ops) +
|
||||
self.spatial_tree.size_of(ops)
|
||||
self.cache_data.size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +174,7 @@ pub struct BuiltDisplayListDescriptor {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DisplayListWithCache {
|
||||
pub display_list: BuiltDisplayList,
|
||||
display_list: BuiltDisplayList,
|
||||
cache: DisplayItemCache,
|
||||
}
|
||||
|
||||
@@ -233,33 +217,13 @@ impl MallocSizeOf for DisplayListWithCache {
|
||||
}
|
||||
}
|
||||
|
||||
/// A debug (human-readable) representation of a built display list that
|
||||
/// can be used for capture and replay.
|
||||
#[cfg(any(feature = "serialize", feature = "deserialize"))]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
struct DisplayListCapture {
|
||||
display_items: Vec<di::DebugDisplayItem>,
|
||||
spatial_tree_items: Vec<di::SpatialTreeItem>,
|
||||
descriptor: BuiltDisplayListDescriptor,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for DisplayListWithCache {
|
||||
fn serialize<S: Serializer>(
|
||||
&self,
|
||||
serializer: S
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
let display_items = BuiltDisplayList::create_debug_display_items(self.iter());
|
||||
let spatial_tree_items = self.display_list.payload.create_debug_spatial_tree_items();
|
||||
|
||||
let dl = DisplayListCapture {
|
||||
display_items,
|
||||
spatial_tree_items,
|
||||
descriptor: self.display_list.descriptor,
|
||||
};
|
||||
|
||||
dl.serialize(serializer)
|
||||
BuiltDisplayList::serialize_with_iterator(serializer, self.iter())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,112 +233,20 @@ impl<'de> Deserialize<'de> for DisplayListWithCache {
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
use crate::display_item::DisplayItem as Real;
|
||||
use crate::display_item::DebugDisplayItem as Debug;
|
||||
|
||||
let capture = DisplayListCapture::deserialize(deserializer)?;
|
||||
|
||||
let mut spatial_tree = Vec::new();
|
||||
for item in capture.spatial_tree_items {
|
||||
poke_into_vec(&item, &mut spatial_tree);
|
||||
}
|
||||
ensure_red_zone::<di::SpatialTreeItem>(&mut spatial_tree);
|
||||
|
||||
let mut items_data = Vec::new();
|
||||
let mut temp = Vec::new();
|
||||
for complete in capture.display_items {
|
||||
let item = match complete {
|
||||
Debug::ClipChain(v, clip_chain_ids) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, clip_chain_ids);
|
||||
Real::ClipChain(v)
|
||||
}
|
||||
Debug::Text(v, glyphs) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, glyphs);
|
||||
Real::Text(v)
|
||||
},
|
||||
Debug::Iframe(v) => {
|
||||
Real::Iframe(v)
|
||||
}
|
||||
Debug::PushReferenceFrame(v) => {
|
||||
Real::PushReferenceFrame(v)
|
||||
}
|
||||
Debug::SetFilterOps(filters) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filters);
|
||||
Real::SetFilterOps
|
||||
},
|
||||
Debug::SetFilterData(filter_data) => {
|
||||
let func_types: Vec<di::ComponentTransferFuncType> =
|
||||
[filter_data.func_r_type,
|
||||
filter_data.func_g_type,
|
||||
filter_data.func_b_type,
|
||||
filter_data.func_a_type].to_vec();
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, func_types);
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.r_values);
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.g_values);
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.b_values);
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.a_values);
|
||||
Real::SetFilterData
|
||||
},
|
||||
Debug::SetFilterPrimitives(filter_primitives) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_primitives);
|
||||
Real::SetFilterPrimitives
|
||||
}
|
||||
Debug::SetGradientStops(stops) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, stops);
|
||||
Real::SetGradientStops
|
||||
},
|
||||
Debug::SetPoints(points) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, points);
|
||||
Real::SetPoints
|
||||
},
|
||||
Debug::RectClip(v) => Real::RectClip(v),
|
||||
Debug::RoundedRectClip(v) => Real::RoundedRectClip(v),
|
||||
Debug::ImageMaskClip(v) => Real::ImageMaskClip(v),
|
||||
Debug::Rectangle(v) => Real::Rectangle(v),
|
||||
Debug::ClearRectangle(v) => Real::ClearRectangle(v),
|
||||
Debug::HitTest(v) => Real::HitTest(v),
|
||||
Debug::Line(v) => Real::Line(v),
|
||||
Debug::Image(v) => Real::Image(v),
|
||||
Debug::RepeatingImage(v) => Real::RepeatingImage(v),
|
||||
Debug::YuvImage(v) => Real::YuvImage(v),
|
||||
Debug::Border(v) => Real::Border(v),
|
||||
Debug::BoxShadow(v) => Real::BoxShadow(v),
|
||||
Debug::Gradient(v) => Real::Gradient(v),
|
||||
Debug::RadialGradient(v) => Real::RadialGradient(v),
|
||||
Debug::ConicGradient(v) => Real::ConicGradient(v),
|
||||
Debug::PushStackingContext(v) => Real::PushStackingContext(v),
|
||||
Debug::PushShadow(v) => Real::PushShadow(v),
|
||||
Debug::BackdropFilter(v) => Real::BackdropFilter(v),
|
||||
|
||||
Debug::PopStackingContext => Real::PopStackingContext,
|
||||
Debug::PopReferenceFrame => Real::PopReferenceFrame,
|
||||
Debug::PopAllShadows => Real::PopAllShadows,
|
||||
};
|
||||
poke_into_vec(&item, &mut items_data);
|
||||
// the aux data is serialized after the item, hence the temporary
|
||||
items_data.extend(temp.drain(..));
|
||||
}
|
||||
|
||||
// Add `DisplayItem::max_size` zone of zeroes to the end of display list
|
||||
// so there is at least this amount available in the display list during
|
||||
// serialization.
|
||||
ensure_red_zone::<di::DisplayItem>(&mut items_data);
|
||||
let display_list = BuiltDisplayList::deserialize(deserializer)?;
|
||||
let cache = DisplayItemCache::new();
|
||||
|
||||
Ok(DisplayListWithCache {
|
||||
display_list: BuiltDisplayList {
|
||||
descriptor: capture.descriptor,
|
||||
payload: DisplayListPayload {
|
||||
cache_data: Vec::new(),
|
||||
items_data,
|
||||
spatial_tree,
|
||||
},
|
||||
},
|
||||
cache: DisplayItemCache::new(),
|
||||
display_list,
|
||||
cache,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl BuiltDisplayListDescriptor {}
|
||||
|
||||
pub struct BuiltDisplayListIter<'a> {
|
||||
list: &'a BuiltDisplayList,
|
||||
data: &'a [u8],
|
||||
cache: Option<&'a DisplayItemCache>,
|
||||
pending_items: std::slice::Iter<'a, CachedDisplayItem>,
|
||||
@@ -463,6 +335,10 @@ pub struct DisplayItemRef<'a: 'b, 'b> {
|
||||
|
||||
// Some of these might just become ItemRanges
|
||||
impl<'a, 'b> DisplayItemRef<'a, 'b> {
|
||||
pub fn display_list(&self) -> &BuiltDisplayList {
|
||||
self.iter.display_list()
|
||||
}
|
||||
|
||||
// Creates a new iterator where this element's iterator is, to hack around borrowck.
|
||||
pub fn sub_iter(&self) -> BuiltDisplayListIter<'a> {
|
||||
self.iter.sub_iter()
|
||||
@@ -572,18 +448,18 @@ impl BuiltDisplayList {
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> BuiltDisplayListIter {
|
||||
BuiltDisplayListIter::new(self.items_data(), None)
|
||||
BuiltDisplayListIter::new(self, self.items_data(), None)
|
||||
}
|
||||
|
||||
pub fn cache_data_iter(&self) -> BuiltDisplayListIter {
|
||||
BuiltDisplayListIter::new(self.cache_data(), None)
|
||||
BuiltDisplayListIter::new(self, self.cache_data(), None)
|
||||
}
|
||||
|
||||
pub fn iter_with_cache<'a>(
|
||||
&'a self,
|
||||
cache: &'a DisplayItemCache
|
||||
) -> BuiltDisplayListIter<'a> {
|
||||
BuiltDisplayListIter::new(self.items_data(), Some(cache))
|
||||
BuiltDisplayListIter::new(self, self.items_data(), Some(cache))
|
||||
}
|
||||
|
||||
pub fn cache_size(&self) -> usize {
|
||||
@@ -594,17 +470,15 @@ impl BuiltDisplayList {
|
||||
self.payload.size_in_bytes()
|
||||
}
|
||||
|
||||
pub fn iter_spatial_tree<F>(&self, f: F) where F: FnMut(&di::SpatialTreeItem) {
|
||||
iter_spatial_tree(&self.payload.spatial_tree, f)
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
pub fn create_debug_display_items(
|
||||
pub fn serialize_with_iterator<S: Serializer>(
|
||||
serializer: S,
|
||||
mut iterator: BuiltDisplayListIter,
|
||||
) -> Vec<di::DebugDisplayItem> {
|
||||
use di::DisplayItem as Real;
|
||||
use di::DebugDisplayItem as Debug;
|
||||
let mut debug_items = Vec::new();
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
use crate::display_item::DisplayItem as Real;
|
||||
use crate::display_item::DebugDisplayItem as Debug;
|
||||
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
|
||||
while let Some(item) = iterator.next_raw() {
|
||||
let serial_di = match *item.item() {
|
||||
@@ -612,6 +486,7 @@ impl BuiltDisplayList {
|
||||
v,
|
||||
item.iter.cur_clip_chain_items.iter().collect()
|
||||
),
|
||||
Real::ScrollFrame(v) => Debug::ScrollFrame(v),
|
||||
Real::Text(v) => Debug::Text(
|
||||
v,
|
||||
item.iter.cur_glyphs.iter().collect()
|
||||
@@ -651,6 +526,7 @@ impl BuiltDisplayList {
|
||||
Real::RectClip(v) => Debug::RectClip(v),
|
||||
Real::RoundedRectClip(v) => Debug::RoundedRectClip(v),
|
||||
Real::ImageMaskClip(v) => Debug::ImageMaskClip(v),
|
||||
Real::StickyFrame(v) => Debug::StickyFrame(v),
|
||||
Real::Rectangle(v) => Debug::Rectangle(v),
|
||||
Real::ClearRectangle(v) => Debug::ClearRectangle(v),
|
||||
Real::HitTest(v) => Debug::HitTest(v),
|
||||
@@ -675,10 +551,9 @@ impl BuiltDisplayList {
|
||||
Real::ReuseItems(_) |
|
||||
Real::RetainedItems(_) => unreachable!("Unexpected item"),
|
||||
};
|
||||
debug_items.push(serial_di);
|
||||
seq.serialize_element(&serial_di)?
|
||||
}
|
||||
|
||||
debug_items
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,10 +574,12 @@ fn skip_slice<'a, T: peek_poke::Peek>(data: &mut &'a [u8]) -> ItemRange<'a, T> {
|
||||
|
||||
impl<'a> BuiltDisplayListIter<'a> {
|
||||
pub fn new(
|
||||
list: &'a BuiltDisplayList,
|
||||
data: &'a [u8],
|
||||
cache: Option<&'a DisplayItemCache>,
|
||||
) -> Self {
|
||||
Self {
|
||||
list,
|
||||
data,
|
||||
cache,
|
||||
pending_items: [].iter(),
|
||||
@@ -725,12 +602,16 @@ impl<'a> BuiltDisplayListIter<'a> {
|
||||
|
||||
pub fn sub_iter(&self) -> Self {
|
||||
let mut iter = BuiltDisplayListIter::new(
|
||||
self.data, self.cache
|
||||
self.list, self.data, self.cache
|
||||
);
|
||||
iter.pending_items = self.pending_items.clone();
|
||||
iter
|
||||
}
|
||||
|
||||
pub fn display_list(&self) -> &'a BuiltDisplayList {
|
||||
self.list
|
||||
}
|
||||
|
||||
pub fn current_item(&self) -> &di::DisplayItem {
|
||||
match self.cur_cached_item {
|
||||
Some(cached_item) => cached_item.display_item(),
|
||||
@@ -980,6 +861,141 @@ impl<'a, T: Copy + peek_poke::Peek> Iterator for AuxIter<'a, T> {
|
||||
|
||||
impl<'a, T: Copy + peek_poke::Peek> ::std::iter::ExactSizeIterator for AuxIter<'a, T> {}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for BuiltDisplayList {
|
||||
fn serialize<S: Serializer>(
|
||||
&self,
|
||||
serializer: S
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
Self::serialize_with_iterator(serializer, self.iter())
|
||||
}
|
||||
}
|
||||
|
||||
// The purpose of this implementation is to deserialize
|
||||
// a display list from one format just to immediately
|
||||
// serialize then into a "built" `Vec<u8>`.
|
||||
|
||||
#[cfg(feature = "deserialize")]
|
||||
impl<'de> Deserialize<'de> for BuiltDisplayList {
|
||||
fn deserialize<D: Deserializer<'de>>(
|
||||
deserializer: D
|
||||
) -> Result<Self, D::Error> {
|
||||
use crate::display_item::DisplayItem as Real;
|
||||
use crate::display_item::DebugDisplayItem as Debug;
|
||||
|
||||
let list = Vec::<Debug>::deserialize(deserializer)?;
|
||||
|
||||
let mut items_data = Vec::new();
|
||||
let mut temp = Vec::new();
|
||||
let mut total_clip_nodes = FIRST_CLIP_NODE_INDEX;
|
||||
let mut total_spatial_nodes = FIRST_SPATIAL_NODE_INDEX;
|
||||
for complete in list {
|
||||
let item = match complete {
|
||||
Debug::ClipChain(v, clip_chain_ids) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, clip_chain_ids);
|
||||
Real::ClipChain(v)
|
||||
}
|
||||
Debug::ScrollFrame(v) => {
|
||||
total_spatial_nodes += 1;
|
||||
total_clip_nodes += 1;
|
||||
Real::ScrollFrame(v)
|
||||
}
|
||||
Debug::StickyFrame(v) => {
|
||||
total_spatial_nodes += 1;
|
||||
Real::StickyFrame(v)
|
||||
}
|
||||
Debug::Text(v, glyphs) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, glyphs);
|
||||
Real::Text(v)
|
||||
},
|
||||
Debug::Iframe(v) => {
|
||||
total_clip_nodes += 1;
|
||||
Real::Iframe(v)
|
||||
}
|
||||
Debug::PushReferenceFrame(v) => {
|
||||
total_spatial_nodes += 1;
|
||||
Real::PushReferenceFrame(v)
|
||||
}
|
||||
Debug::SetFilterOps(filters) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filters);
|
||||
Real::SetFilterOps
|
||||
},
|
||||
Debug::SetFilterData(filter_data) => {
|
||||
let func_types: Vec<di::ComponentTransferFuncType> =
|
||||
[filter_data.func_r_type,
|
||||
filter_data.func_g_type,
|
||||
filter_data.func_b_type,
|
||||
filter_data.func_a_type].to_vec();
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, func_types);
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.r_values);
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.g_values);
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.b_values);
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.a_values);
|
||||
Real::SetFilterData
|
||||
},
|
||||
Debug::SetFilterPrimitives(filter_primitives) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, filter_primitives);
|
||||
Real::SetFilterPrimitives
|
||||
}
|
||||
Debug::SetGradientStops(stops) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, stops);
|
||||
Real::SetGradientStops
|
||||
},
|
||||
Debug::SetPoints(points) => {
|
||||
DisplayListBuilder::push_iter_impl(&mut temp, points);
|
||||
Real::SetPoints
|
||||
},
|
||||
Debug::RectClip(v) => Real::RectClip(v),
|
||||
Debug::RoundedRectClip(v) => Real::RoundedRectClip(v),
|
||||
Debug::ImageMaskClip(v) => Real::ImageMaskClip(v),
|
||||
Debug::Rectangle(v) => Real::Rectangle(v),
|
||||
Debug::ClearRectangle(v) => Real::ClearRectangle(v),
|
||||
Debug::HitTest(v) => Real::HitTest(v),
|
||||
Debug::Line(v) => Real::Line(v),
|
||||
Debug::Image(v) => Real::Image(v),
|
||||
Debug::RepeatingImage(v) => Real::RepeatingImage(v),
|
||||
Debug::YuvImage(v) => Real::YuvImage(v),
|
||||
Debug::Border(v) => Real::Border(v),
|
||||
Debug::BoxShadow(v) => Real::BoxShadow(v),
|
||||
Debug::Gradient(v) => Real::Gradient(v),
|
||||
Debug::RadialGradient(v) => Real::RadialGradient(v),
|
||||
Debug::ConicGradient(v) => Real::ConicGradient(v),
|
||||
Debug::PushStackingContext(v) => Real::PushStackingContext(v),
|
||||
Debug::PushShadow(v) => Real::PushShadow(v),
|
||||
Debug::BackdropFilter(v) => Real::BackdropFilter(v),
|
||||
|
||||
Debug::PopStackingContext => Real::PopStackingContext,
|
||||
Debug::PopReferenceFrame => Real::PopReferenceFrame,
|
||||
Debug::PopAllShadows => Real::PopAllShadows,
|
||||
};
|
||||
poke_into_vec(&item, &mut items_data);
|
||||
// the aux data is serialized after the item, hence the temporary
|
||||
items_data.extend(temp.drain(..));
|
||||
}
|
||||
|
||||
// Add `DisplayItem::max_size` zone of zeroes to the end of display list
|
||||
// so there is at least this amount available in the display list during
|
||||
// serialization.
|
||||
ensure_red_zone::<di::DisplayItem>(&mut items_data);
|
||||
|
||||
Ok(BuiltDisplayList {
|
||||
payload: DisplayListPayload {
|
||||
items_data,
|
||||
cache_data: Vec::new(),
|
||||
},
|
||||
descriptor: BuiltDisplayListDescriptor {
|
||||
gecko_display_list_type: GeckoDisplayListType::None,
|
||||
builder_start_time: 0,
|
||||
builder_finish_time: 1,
|
||||
send_start_time: 1,
|
||||
total_clip_nodes,
|
||||
total_spatial_nodes,
|
||||
cache_size: 0,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SaveState {
|
||||
dl_items_len: usize,
|
||||
@@ -1000,23 +1016,6 @@ pub enum DisplayListSection {
|
||||
Chunk,
|
||||
}
|
||||
|
||||
/// A small portion of a normal spatial node that we store during DL construction to
|
||||
/// enable snapping and reference frame <-> stacking context coord mapping. In future
|
||||
/// we'll aim to remove this and have the full spatial tree available during DL build.
|
||||
#[derive(Clone)]
|
||||
pub struct SpatialNodeInfo {
|
||||
/// The total external scroll offset applicable at this node
|
||||
accumulated_external_scroll_offset: LayoutVector2D,
|
||||
}
|
||||
|
||||
impl SpatialNodeInfo {
|
||||
fn identity() -> Self {
|
||||
SpatialNodeInfo {
|
||||
accumulated_external_scroll_offset: LayoutVector2D::zero(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DisplayListBuilder {
|
||||
payload: DisplayListPayload,
|
||||
@@ -1034,19 +1033,12 @@ pub struct DisplayListBuilder {
|
||||
|
||||
cache_size: usize,
|
||||
serialized_content_buffer: Option<String>,
|
||||
|
||||
/// Helper struct to map stacking context coords <-> reference frame coords.
|
||||
rf_mapper: ReferenceFrameMapper,
|
||||
|
||||
/// Minimal info about encountered spatial nodes to allow snapping during DL building
|
||||
spatial_nodes: Vec<SpatialNodeInfo>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DisplayListCapacity {
|
||||
items_size: usize,
|
||||
cache_size: usize,
|
||||
spatial_tree_size: usize,
|
||||
}
|
||||
|
||||
impl DisplayListCapacity {
|
||||
@@ -1054,7 +1046,6 @@ impl DisplayListCapacity {
|
||||
DisplayListCapacity {
|
||||
items_size: 0,
|
||||
cache_size: 0,
|
||||
spatial_tree_size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1074,7 +1065,6 @@ impl DisplayListBuilder {
|
||||
payload: DisplayListPayload {
|
||||
items_data: Vec::with_capacity(capacity.items_size),
|
||||
cache_data: Vec::with_capacity(capacity.cache_size),
|
||||
spatial_tree: Vec::with_capacity(capacity.spatial_tree_size),
|
||||
},
|
||||
pipeline_id,
|
||||
|
||||
@@ -1088,9 +1078,6 @@ impl DisplayListBuilder {
|
||||
save_state: None,
|
||||
cache_size: 0,
|
||||
serialized_content_buffer: None,
|
||||
|
||||
rf_mapper: ReferenceFrameMapper::new(),
|
||||
spatial_nodes: vec![SpatialNodeInfo::identity(); FIRST_SPATIAL_NODE_INDEX + 1],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1226,11 +1213,6 @@ impl DisplayListBuilder {
|
||||
self.push_item_to_section(item, self.default_section());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn push_spatial_tree_item(&mut self, item: &di::SpatialTreeItem) {
|
||||
poke_into_vec(item, &mut self.payload.spatial_tree);
|
||||
}
|
||||
|
||||
fn push_iter_impl<I>(data: &mut Vec<u8>, iter_source: I)
|
||||
where
|
||||
I: IntoIterator,
|
||||
@@ -1617,15 +1599,7 @@ impl DisplayListBuilder {
|
||||
) -> di::SpatialId {
|
||||
let id = self.generate_spatial_index();
|
||||
|
||||
let current_offset = self.current_offset(parent_spatial_id);
|
||||
let origin = origin + current_offset;
|
||||
|
||||
self.add_spatial_node_info(
|
||||
id,
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
let descriptor = di::SpatialTreeItem::ReferenceFrame(di::ReferenceFrameDescriptor {
|
||||
let item = di::DisplayItem::PushReferenceFrame(di::ReferenceFrameDisplayListItem {
|
||||
parent_spatial_id,
|
||||
origin,
|
||||
reference_frame: di::ReferenceFrame {
|
||||
@@ -1637,14 +1611,8 @@ impl DisplayListBuilder {
|
||||
id,
|
||||
},
|
||||
});
|
||||
self.push_spatial_tree_item(&descriptor);
|
||||
|
||||
self.rf_mapper.push_scope();
|
||||
|
||||
let item = di::DisplayItem::PushReferenceFrame(di::ReferenceFrameDisplayListItem {
|
||||
});
|
||||
self.push_item(&item);
|
||||
|
||||
id
|
||||
}
|
||||
|
||||
@@ -1658,10 +1626,7 @@ impl DisplayListBuilder {
|
||||
) -> di::SpatialId {
|
||||
let id = self.generate_spatial_index();
|
||||
|
||||
let current_offset = self.current_offset(parent_spatial_id);
|
||||
let origin = origin + current_offset;
|
||||
|
||||
let descriptor = di::SpatialTreeItem::ReferenceFrame(di::ReferenceFrameDescriptor {
|
||||
let item = di::DisplayItem::PushReferenceFrame(di::ReferenceFrameDisplayListItem {
|
||||
parent_spatial_id,
|
||||
origin,
|
||||
reference_frame: di::ReferenceFrame {
|
||||
@@ -1678,19 +1643,12 @@ impl DisplayListBuilder {
|
||||
id,
|
||||
},
|
||||
});
|
||||
self.push_spatial_tree_item(&descriptor);
|
||||
|
||||
self.rf_mapper.push_scope();
|
||||
|
||||
let item = di::DisplayItem::PushReferenceFrame(di::ReferenceFrameDisplayListItem {
|
||||
});
|
||||
self.push_item(&item);
|
||||
|
||||
id
|
||||
}
|
||||
|
||||
pub fn pop_reference_frame(&mut self) {
|
||||
self.rf_mapper.pop_scope();
|
||||
self.push_item(&di::DisplayItem::PopReferenceFrame);
|
||||
}
|
||||
|
||||
@@ -1723,7 +1681,6 @@ impl DisplayListBuilder {
|
||||
},
|
||||
});
|
||||
|
||||
self.rf_mapper.push_offset(origin.to_vector());
|
||||
self.push_item(&item);
|
||||
}
|
||||
|
||||
@@ -1770,7 +1727,6 @@ impl DisplayListBuilder {
|
||||
}
|
||||
|
||||
pub fn pop_stacking_context(&mut self) {
|
||||
self.rf_mapper.pop_offset();
|
||||
self.push_item(&di::DisplayItem::PopStackingContext);
|
||||
}
|
||||
|
||||
@@ -1851,15 +1807,7 @@ impl DisplayListBuilder {
|
||||
external_scroll_offset: LayoutVector2D,
|
||||
) -> di::SpatialId {
|
||||
let scroll_frame_id = self.generate_spatial_index();
|
||||
|
||||
let parent = self.spatial_nodes[parent_space.0].clone();
|
||||
|
||||
self.add_spatial_node_info(
|
||||
scroll_frame_id,
|
||||
parent.accumulated_external_scroll_offset + external_scroll_offset,
|
||||
);
|
||||
|
||||
let descriptor = di::SpatialTreeItem::ScrollFrame(di::ScrollFrameDescriptor {
|
||||
let item = di::DisplayItem::ScrollFrame(di::ScrollFrameDisplayItem {
|
||||
content_rect,
|
||||
frame_rect,
|
||||
parent_space,
|
||||
@@ -1869,7 +1817,7 @@ impl DisplayListBuilder {
|
||||
external_scroll_offset,
|
||||
});
|
||||
|
||||
self.push_spatial_tree_item(&descriptor);
|
||||
self.push_item(&item);
|
||||
|
||||
scroll_frame_id
|
||||
}
|
||||
@@ -1958,14 +1906,7 @@ impl DisplayListBuilder {
|
||||
previously_applied_offset: LayoutVector2D,
|
||||
) -> di::SpatialId {
|
||||
let id = self.generate_spatial_index();
|
||||
let parent = self.spatial_nodes[parent_spatial_id.0].clone();
|
||||
|
||||
self.add_spatial_node_info(
|
||||
id,
|
||||
parent.accumulated_external_scroll_offset,
|
||||
);
|
||||
|
||||
let descriptor = di::SpatialTreeItem::StickyFrame(di::StickyFrameDescriptor {
|
||||
let item = di::DisplayItem::StickyFrame(di::StickyFrameDisplayItem {
|
||||
parent_spatial_id,
|
||||
id,
|
||||
bounds: frame_rect,
|
||||
@@ -1975,7 +1916,7 @@ impl DisplayListBuilder {
|
||||
previously_applied_offset,
|
||||
});
|
||||
|
||||
self.push_spatial_tree_item(&descriptor);
|
||||
self.push_item(&item);
|
||||
id
|
||||
}
|
||||
|
||||
@@ -2088,7 +2029,6 @@ impl DisplayListBuilder {
|
||||
// serialization.
|
||||
ensure_red_zone::<di::DisplayItem>(&mut self.payload.items_data);
|
||||
ensure_red_zone::<di::DisplayItem>(&mut self.payload.cache_data);
|
||||
ensure_red_zone::<di::SpatialTreeItem>(&mut self.payload.spatial_tree);
|
||||
|
||||
let end_time = precise_time_ns();
|
||||
(
|
||||
@@ -2107,117 +2047,4 @@ impl DisplayListBuilder {
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Retrieve the current offset to allow converting a stacking context
|
||||
/// relative coordinate to be relative to the owing reference frame,
|
||||
/// also considering any external scroll offset on the provided
|
||||
/// spatial node.
|
||||
fn current_offset(
|
||||
&mut self,
|
||||
spatial_id: di::SpatialId,
|
||||
) -> LayoutVector2D {
|
||||
// Get the current offset from stacking context <-> reference frame space.
|
||||
let rf_offset = self.rf_mapper.current_offset();
|
||||
|
||||
// Get the external scroll offset, if applicable.
|
||||
let scroll_offset = self.spatial_nodes[spatial_id.0].accumulated_external_scroll_offset;
|
||||
|
||||
rf_offset + scroll_offset
|
||||
}
|
||||
|
||||
/// Add info about a spatial node that is needed during DL building.
|
||||
fn add_spatial_node_info(
|
||||
&mut self,
|
||||
id: di::SpatialId,
|
||||
accumulated_external_scroll_offset: LayoutVector2D,
|
||||
) {
|
||||
self.spatial_nodes.resize(id.0 + 1, SpatialNodeInfo::identity());
|
||||
|
||||
let info = &mut self.spatial_nodes[id.0];
|
||||
info.accumulated_external_scroll_offset = accumulated_external_scroll_offset;
|
||||
}
|
||||
}
|
||||
|
||||
fn iter_spatial_tree<F>(spatial_tree: &[u8], mut f: F) where F: FnMut(&di::SpatialTreeItem) {
|
||||
let mut src = spatial_tree;
|
||||
let mut item = di::SpatialTreeItem::Invalid;
|
||||
|
||||
while src.len() > di::SpatialTreeItem::max_size() {
|
||||
src = peek_from_slice(src, &mut item);
|
||||
f(&item);
|
||||
}
|
||||
}
|
||||
|
||||
/// The offset stack for a given reference frame.
|
||||
#[derive(Clone)]
|
||||
struct ReferenceFrameState {
|
||||
/// A stack of current offsets from the current reference frame scope.
|
||||
offsets: Vec<LayoutVector2D>,
|
||||
}
|
||||
|
||||
/// Maps from stacking context layout coordinates into reference frame
|
||||
/// relative coordinates.
|
||||
#[derive(Clone)]
|
||||
pub struct ReferenceFrameMapper {
|
||||
/// A stack of reference frame scopes.
|
||||
frames: Vec<ReferenceFrameState>,
|
||||
}
|
||||
|
||||
impl ReferenceFrameMapper {
|
||||
pub fn new() -> Self {
|
||||
ReferenceFrameMapper {
|
||||
frames: vec![
|
||||
ReferenceFrameState {
|
||||
offsets: vec![
|
||||
LayoutVector2D::zero(),
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/// Push a new scope. This resets the current offset to zero, and is
|
||||
/// used when a new reference frame or iframe is pushed.
|
||||
pub fn push_scope(&mut self) {
|
||||
self.frames.push(ReferenceFrameState {
|
||||
offsets: vec![
|
||||
LayoutVector2D::zero(),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/// Pop a reference frame scope off the stack.
|
||||
pub fn pop_scope(&mut self) {
|
||||
self.frames.pop().unwrap();
|
||||
}
|
||||
|
||||
/// Push a new offset for the current scope. This is used when
|
||||
/// a new stacking context is pushed.
|
||||
pub fn push_offset(&mut self, offset: LayoutVector2D) {
|
||||
let frame = self.frames.last_mut().unwrap();
|
||||
let current_offset = *frame.offsets.last().unwrap();
|
||||
frame.offsets.push(current_offset + offset);
|
||||
}
|
||||
|
||||
/// Pop a local stacking context offset from the current scope.
|
||||
pub fn pop_offset(&mut self) {
|
||||
let frame = self.frames.last_mut().unwrap();
|
||||
frame.offsets.pop().unwrap();
|
||||
}
|
||||
|
||||
/// Retrieve the current offset to allow converting a stacking context
|
||||
/// relative coordinate to be relative to the owing reference frame.
|
||||
/// TODO(gw): We could perhaps have separate coordinate spaces for this,
|
||||
/// however that's going to either mean a lot of changes to
|
||||
/// public API code, or a lot of changes to internal code.
|
||||
/// Before doing that, we should revisit how Gecko would
|
||||
/// prefer to provide coordinates.
|
||||
/// TODO(gw): For now, this includes only the reference frame relative
|
||||
/// offset. Soon, we will expand this to include the initial
|
||||
/// scroll offsets that are now available on scroll nodes. This
|
||||
/// will allow normalizing the coordinates even between display
|
||||
/// lists where APZ has scrolled the content.
|
||||
pub fn current_offset(&self) -> LayoutVector2D {
|
||||
*self.frames.last().unwrap().offsets.last().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ fuzzy(0-20,0-999) fails-if(OSX>=1008&&!skiaContent) != downscale-2e.html?205,53,
|
||||
|
||||
# Skip on Android because it runs reftests via http, and moz-icon isn't
|
||||
# accessible from http/https origins anymore.
|
||||
fuzzy(0-25,0-3940) fuzzy-if(gtkWidget&&!webrender,4-4,2616-2616) fuzzy-if(gtkWidget&&!webrender&&!layersGPUAccelerated,0-0,0-0) fuzzy-if(gtkWidget&&webrender,0-0,0-0) skip-if(Android) fuzzy-if(appleSilicon,0-20,0-10123) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # gtkWidget Bug 1592059: regular is 2616, no-accel is 0, qr passes with 0
|
||||
fuzzy(0-17,0-3940) fuzzy-if(gtkWidget&&!webrender,4-4,2616-2616) fuzzy-if(gtkWidget&&!webrender&&!layersGPUAccelerated,0-0,0-0) fuzzy-if(gtkWidget&&webrender,0-0,0-0) skip-if(Android) fuzzy-if(appleSilicon,0-20,0-10123) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # gtkWidget Bug 1592059: regular is 2616, no-accel is 0, qr passes with 0
|
||||
|
||||
== downscale-png.html?16,16,interlaced downscale-png.html?16,16,normal
|
||||
== downscale-png.html?24,24,interlaced downscale-png.html?24,24,normal
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[devicepixel.html]
|
||||
fuzzy: maxDifference=0-52;totalPixels=0-1100
|
||||
fuzzy: maxDifference=0-2;totalPixels=0-1391
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1723618
|
||||
|
||||
Reference in New Issue
Block a user