Bug 1720624 - Remove WrSpaceAndClip type r=nical

This was used when defining scroll layers and also backdrop-filter.

Removing it from the scroll layer API allows removal of the implicit
clip rect that a scroll node previously created (Gecko doesn't use
this). To maintain compatibility with wrench tests, add a flag that
allows a test to specify a clip rect should be created for the scroll
layer (we should remove this from wrench in future and port the tests
to create explicit clip rects as required).

The usage of backdrop-filter was the only remaining place this type
was used, so it's now ported to use the clip-chain API.

This simplifies the scroll layer API and removes an extra clip rect
from each scroll layer instance, as a small performance improvement.

Differential Revision: https://phabricator.services.mozilla.com/D119938
This commit is contained in:
Glenn Watson 2021-07-18 22:32:27 +00:00
parent 70a94bffbb
commit a34d3f438e
22 changed files with 171 additions and 161 deletions

View File

@ -89,14 +89,13 @@ void ClipManager::EndList(const StackingContextHelper& aStackingContext) {
void ClipManager::PushOverrideForASR(const ActiveScrolledRoot* aASR,
const wr::WrSpatialId& aSpatialId) {
Maybe<wr::WrSpaceAndClip> spaceAndClip = GetScrollLayer(aASR);
MOZ_ASSERT(spaceAndClip.isSome());
Maybe<wr::WrSpatialId> space = GetScrollLayer(aASR);
MOZ_ASSERT(space.isSome());
CLIP_LOG("Pushing %p override %zu -> %s\n", aASR, spaceAndClip->space.id,
CLIP_LOG("Pushing %p override %zu -> %s\n", aASR, space->id,
ToString(aSpatialId.id).c_str());
auto it =
mASROverride.insert({spaceAndClip->space, std::stack<wr::WrSpatialId>()});
auto it = mASROverride.insert({*space, std::stack<wr::WrSpatialId>()});
it.first->second.push(aSpatialId);
// Start a new cache
@ -107,11 +106,11 @@ void ClipManager::PopOverrideForASR(const ActiveScrolledRoot* aASR) {
MOZ_ASSERT(!mCacheStack.empty());
mCacheStack.pop();
Maybe<wr::WrSpaceAndClip> spaceAndClip = GetScrollLayer(aASR);
MOZ_ASSERT(spaceAndClip.isSome());
Maybe<wr::WrSpatialId> space = GetScrollLayer(aASR);
MOZ_ASSERT(space.isSome());
auto it = mASROverride.find(spaceAndClip->space);
CLIP_LOG("Popping %p override %zu -> %s\n", aASR, spaceAndClip->space.id,
auto it = mASROverride.find(*space);
CLIP_LOG("Popping %p override %zu -> %s\n", aASR, space->id,
ToString(it->second.top().id).c_str());
it->second.pop();
@ -215,18 +214,17 @@ wr::WrSpaceAndClipChain ClipManager::SwitchItem(nsDisplayItem* aItem) {
if (clip) {
leafmostASR = ActiveScrolledRoot::PickDescendant(leafmostASR, clip->mASR);
}
Maybe<wr::WrSpaceAndClip> leafmostId = DefineScrollLayers(leafmostASR, aItem);
Maybe<wr::WrSpatialId> leafmostId = DefineScrollLayers(leafmostASR, aItem);
Unused << leafmostId;
// Define all the clips in the item's clip chain, and obtain a clip chain id
// for it.
clips.mClipChainId = DefineClipChain(clip, auPerDevPixel);
Maybe<wr::WrSpaceAndClip> spaceAndClip = GetScrollLayer(asr);
MOZ_ASSERT(spaceAndClip.isSome());
clips.mScrollId = SpatialIdAfterOverride(spaceAndClip->space);
CLIP_LOG("\tassigning %d -> %d\n", (int)spaceAndClip->space.id,
(int)clips.mScrollId.id);
Maybe<wr::WrSpatialId> space = GetScrollLayer(asr);
MOZ_ASSERT(space.isSome());
clips.mScrollId = SpatialIdAfterOverride(*space);
CLIP_LOG("\tassigning %d -> %d\n", (int)space->id, (int)clips.mScrollId.id);
// Now that we have the scroll id and a clip id for the item, push it onto
// the WR stack.
@ -238,13 +236,13 @@ wr::WrSpaceAndClipChain ClipManager::SwitchItem(nsDisplayItem* aItem) {
return spaceAndClipChain;
}
Maybe<wr::WrSpaceAndClip> ClipManager::GetScrollLayer(
Maybe<wr::WrSpatialId> ClipManager::GetScrollLayer(
const ActiveScrolledRoot* aASR) {
for (const ActiveScrolledRoot* asr = aASR; asr; asr = asr->mParent) {
Maybe<wr::WrSpaceAndClip> spaceAndClip =
Maybe<wr::WrSpatialId> space =
mBuilder->GetScrollIdForDefinedScrollLayer(asr->GetViewId());
if (spaceAndClip) {
return spaceAndClip;
if (space) {
return space;
}
// If this ASR doesn't have a scroll ID, then we should check its ancestor.
@ -252,28 +250,27 @@ Maybe<wr::WrSpaceAndClip> ClipManager::GetScrollLayer(
// failed to get the scroll metadata.
}
Maybe<wr::WrSpaceAndClip> spaceAndClip =
mBuilder->GetScrollIdForDefinedScrollLayer(
ScrollableLayerGuid::NULL_SCROLL_ID);
MOZ_ASSERT(spaceAndClip.isSome());
return spaceAndClip;
Maybe<wr::WrSpatialId> space = mBuilder->GetScrollIdForDefinedScrollLayer(
ScrollableLayerGuid::NULL_SCROLL_ID);
MOZ_ASSERT(space.isSome());
return space;
}
Maybe<wr::WrSpaceAndClip> ClipManager::DefineScrollLayers(
Maybe<wr::WrSpatialId> ClipManager::DefineScrollLayers(
const ActiveScrolledRoot* aASR, nsDisplayItem* aItem) {
if (!aASR) {
// Recursion base case
return Nothing();
}
ScrollableLayerGuid::ViewID viewId = aASR->GetViewId();
Maybe<wr::WrSpaceAndClip> spaceAndClip =
Maybe<wr::WrSpatialId> space =
mBuilder->GetScrollIdForDefinedScrollLayer(viewId);
if (spaceAndClip) {
if (space) {
// If we've already defined this scroll layer before, we can early-exit
return spaceAndClip;
return space;
}
// Recurse to define the ancestors
Maybe<wr::WrSpaceAndClip> ancestorSpaceAndClip =
Maybe<wr::WrSpatialId> ancestorSpace =
DefineScrollLayers(aASR->mParent, aItem);
Maybe<ScrollMetadata> metadata =
@ -281,13 +278,13 @@ Maybe<wr::WrSpaceAndClip> ClipManager::DefineScrollLayers(
mManager, aItem->ReferenceFrame(), Nothing(), nullptr);
if (!metadata) {
MOZ_ASSERT_UNREACHABLE("Expected scroll metadata to be available!");
return ancestorSpaceAndClip;
return ancestorSpace;
}
FrameMetrics& metrics = metadata->GetMetrics();
if (!metrics.IsScrollable()) {
// This item is a scrolling no-op, skip over it in the ASR chain.
return ancestorSpaceAndClip;
return ancestorSpace;
}
nsIScrollableFrame* scrollableFrame = aASR->mScrollableFrame;
@ -311,9 +308,9 @@ Maybe<wr::WrSpaceAndClip> ClipManager::DefineScrollLayers(
metrics.GetExpandedScrollableRect() * metrics.GetDevPixelsPerCSSPixel();
contentRect.MoveTo(clipBounds.TopLeft());
Maybe<wr::WrSpaceAndClip> parent = ancestorSpaceAndClip;
Maybe<wr::WrSpatialId> parent = ancestorSpace;
if (parent) {
parent->space = SpatialIdAfterOverride(parent->space);
*parent = SpatialIdAfterOverride(*parent);
}
// The external scroll offset is accumulated into the local space positions of
// display items inside WR, so that the elements hash (intern) to the same
@ -355,24 +352,22 @@ Maybe<wr::WrClipChainId> ClipManager::DefineClipChain(
AutoTArray<wr::ComplexClipRegion, 6> wrRoundedRects;
chain->mClip.ToComplexClipRegions(aAppUnitsPerDevPixel, wrRoundedRects);
Maybe<wr::WrSpaceAndClip> spaceAndClip = GetScrollLayer(chain->mASR);
Maybe<wr::WrSpatialId> space = GetScrollLayer(chain->mASR);
// Before calling DefineClipChain we defined the ASRs by calling
// DefineScrollLayers, so we must have a scrollId here.
MOZ_ASSERT(spaceAndClip.isSome());
MOZ_ASSERT(space.isSome());
// Define the clip
spaceAndClip->space = SpatialIdAfterOverride(spaceAndClip->space);
*space = SpatialIdAfterOverride(*space);
AutoTArray<wr::WrClipId, 4> chainClipIds;
auto rectClipId = mBuilder->DefineRectClip(Some(spaceAndClip->space),
wr::ToLayoutRect(clip));
auto rectClipId = mBuilder->DefineRectClip(space, wr::ToLayoutRect(clip));
CLIP_LOG("cache[%p] <= %zu\n", chain, rectClipId);
chainClipIds.AppendElement(rectClipId);
for (const auto& complexClip : wrRoundedRects) {
auto complexClipId = mBuilder->DefineRoundedRectClip(
Some(spaceAndClip->space), complexClip);
auto complexClipId = mBuilder->DefineRoundedRectClip(space, complexClip);
CLIP_LOG("cache[%p] <= %zu\n", chain, complexClipId);
chainClipIds.AppendElement(complexClipId);
}

View File

@ -70,10 +70,10 @@ class ClipManager {
private:
wr::WrSpatialId SpatialIdAfterOverride(const wr::WrSpatialId& aSpatialId);
Maybe<wr::WrSpaceAndClip> GetScrollLayer(const ActiveScrolledRoot* aASR);
Maybe<wr::WrSpatialId> GetScrollLayer(const ActiveScrolledRoot* aASR);
Maybe<wr::WrSpaceAndClip> DefineScrollLayers(const ActiveScrolledRoot* aASR,
nsDisplayItem* aItem);
Maybe<wr::WrSpatialId> DefineScrollLayers(const ActiveScrolledRoot* aASR,
nsDisplayItem* aItem);
Maybe<wr::WrClipChainId> DefineClipChain(const DisplayItemClipChain* aChain,
int32_t aAppUnitsPerDevPixel);

View File

@ -1125,7 +1125,7 @@ wr::WrSpatialId DisplayListBuilder::DefineStickyFrame(
return spatialId;
}
Maybe<wr::WrSpaceAndClip> DisplayListBuilder::GetScrollIdForDefinedScrollLayer(
Maybe<wr::WrSpatialId> DisplayListBuilder::GetScrollIdForDefinedScrollLayer(
layers::ScrollableLayerGuid::ViewID aViewId) const {
if (aViewId == layers::ScrollableLayerGuid::NULL_SCROLL_ID) {
return Some(wr::RootScrollNode());
@ -1139,32 +1139,29 @@ Maybe<wr::WrSpaceAndClip> DisplayListBuilder::GetScrollIdForDefinedScrollLayer(
return Some(it->second);
}
wr::WrSpaceAndClip DisplayListBuilder::DefineScrollLayer(
wr::WrSpatialId DisplayListBuilder::DefineScrollLayer(
const layers::ScrollableLayerGuid::ViewID& aViewId,
const Maybe<wr::WrSpaceAndClip>& aParent,
const wr::LayoutRect& aContentRect, const wr::LayoutRect& aClipRect,
const wr::LayoutPoint& aScrollOffset) {
const Maybe<wr::WrSpatialId>& aParent, const wr::LayoutRect& aContentRect,
const wr::LayoutRect& aClipRect, const wr::LayoutPoint& aScrollOffset) {
auto it = mScrollIds.find(aViewId);
if (it != mScrollIds.end()) {
return it->second;
}
// We haven't defined aViewId before, so let's define it now.
wr::WrSpaceAndClip defaultParent = wr::RootScrollNode();
// Note: we are currently ignoring the clipId on the stack here
defaultParent.space = mCurrentSpaceAndClipChain.space;
wr::WrSpatialId defaultParent = mCurrentSpaceAndClipChain.space;
auto spaceAndClip = wr_dp_define_scroll_layer(
auto space = wr_dp_define_scroll_layer(
mWrState, aViewId, aParent ? aParent.ptr() : &defaultParent, aContentRect,
aClipRect, aScrollOffset);
WRDL_LOG("DefineScrollLayer id=%" PRIu64 "/%zu p=%s co=%s cl=%s\n", mWrState,
aViewId, spaceAndClip.space.id,
aViewId, space->id,
aParent ? ToString(aParent->space.id).c_str() : "(nil)",
ToString(aContentRect).c_str(), ToString(aClipRect).c_str());
mScrollIds[aViewId] = spaceAndClip;
return spaceAndClip;
mScrollIds[aViewId] = space;
return space;
}
void DisplayListBuilder::PushRect(const wr::LayoutRect& aBounds,
@ -1257,12 +1254,14 @@ void DisplayListBuilder::PushBackdropFilter(
ToString(aBounds).c_str(), ToString(clip).c_str());
auto clipId = DefineRoundedRectClip(Nothing(), aRegion);
auto spaceAndClip = WrSpaceAndClip{mCurrentSpaceAndClipChain.space, clipId};
auto clipChainId = DefineClipChain({clipId}, true);
auto spaceAndClip =
WrSpaceAndClipChain{mCurrentSpaceAndClipChain.space, clipChainId.id};
wr_dp_push_backdrop_filter_with_parent_clip(
mWrState, aBounds, clip, aIsBackfaceVisible, &spaceAndClip,
aFilters.Elements(), aFilters.Length(), aFilterDatas.Elements(),
aFilterDatas.Length());
wr_dp_push_backdrop_filter(mWrState, aBounds, clip, aIsBackfaceVisible,
&spaceAndClip, aFilters.Elements(),
aFilters.Length(), aFilterDatas.Elements(),
aFilterDatas.Length());
}
void DisplayListBuilder::PushLinearGradient(

View File

@ -472,13 +472,12 @@ class DisplayListBuilder final {
const StickyOffsetBounds& aHorizontalBounds,
const wr::LayoutVector2D& aAppliedOffset);
Maybe<wr::WrSpaceAndClip> GetScrollIdForDefinedScrollLayer(
Maybe<wr::WrSpatialId> GetScrollIdForDefinedScrollLayer(
layers::ScrollableLayerGuid::ViewID aViewId) const;
wr::WrSpaceAndClip DefineScrollLayer(
wr::WrSpatialId DefineScrollLayer(
const layers::ScrollableLayerGuid::ViewID& aViewId,
const Maybe<wr::WrSpaceAndClip>& aParent,
const wr::LayoutRect& aContentRect, const wr::LayoutRect& aClipRect,
const wr::LayoutPoint& aScrollOffset);
const Maybe<wr::WrSpatialId>& aParent, const wr::LayoutRect& aContentRect,
const wr::LayoutRect& aClipRect, const wr::LayoutPoint& aScrollOffset);
void PushRect(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
bool aIsBackfaceVisible, const wr::ColorF& aColor);
@ -725,7 +724,7 @@ class DisplayListBuilder final {
// Track each scroll id that we encountered. We use this structure to
// ensure that we don't define a particular scroll layer multiple times,
// as that results in undefined behaviour in WR.
std::unordered_map<layers::ScrollableLayerGuid::ViewID, wr::WrSpaceAndClip>
std::unordered_map<layers::ScrollableLayerGuid::ViewID, wr::WrSpatialId>
mScrollIds;
wr::WrSpaceAndClipChain mCurrentSpaceAndClipChain;

View File

@ -74,12 +74,7 @@ void Assign_WrVecU8(wr::WrVecU8& aVec, mozilla::ipc::ByteBuf&& aOther) {
aOther.mCapacity = 0;
}
WrSpaceAndClip RootScrollNode() {
WrSpaceAndClip sac;
sac.clip = wr_root_clip_id();
sac.space = wr_root_scroll_node_id();
return sac;
}
WrSpatialId RootScrollNode() { return wr_root_scroll_node_id(); }
WrSpaceAndClipChain RootScrollNodeWithChain() {
WrSpaceAndClipChain sacc;

View File

@ -755,7 +755,7 @@ struct WrClipChainId {
}
};
WrSpaceAndClip RootScrollNode();
WrSpatialId RootScrollNode();
WrSpaceAndClipChain RootScrollNodeWithChain();
WrSpaceAndClipChain InvalidScrollNodeWithChain();

View File

@ -111,28 +111,6 @@ type WrColorDepth = ColorDepth;
/// cbindgen:field-names=[mNamespace, mHandle]
type WrColorRange = ColorRange;
#[repr(C)]
pub struct WrSpaceAndClip {
space: WrSpatialId,
clip: WrClipId,
}
impl WrSpaceAndClip {
fn from_webrender(sac: SpaceAndClipInfo) -> Self {
WrSpaceAndClip {
space: WrSpatialId { id: sac.spatial_id.0 },
clip: WrClipId::from_webrender(sac.clip_id),
}
}
fn to_webrender(&self, pipeline_id: WrPipelineId) -> SpaceAndClipInfo {
SpaceAndClipInfo {
spatial_id: self.space.to_webrender(pipeline_id),
clip_id: self.clip.to_webrender(pipeline_id),
}
}
}
#[inline]
fn clip_chain_id_to_webrender(id: u64, pipeline_id: WrPipelineId) -> ClipId {
if id == ROOT_CLIP_CHAIN {
@ -2764,15 +2742,15 @@ pub extern "C" fn wr_dp_define_sticky_frame(
pub extern "C" fn wr_dp_define_scroll_layer(
state: &mut WrState,
external_scroll_id: u64,
parent: &WrSpaceAndClip,
parent: &WrSpatialId,
content_rect: LayoutRect,
clip_rect: LayoutRect,
scroll_offset: LayoutPoint,
) -> WrSpaceAndClip {
) -> WrSpatialId {
assert!(unsafe { is_in_main_thread() });
let space_and_clip = state.frame_builder.dl_builder.define_scroll_frame(
&parent.to_webrender(state.pipeline_id),
parent.to_webrender(state.pipeline_id),
ExternalScrollId(external_scroll_id, state.pipeline_id),
content_rect,
clip_rect,
@ -2782,7 +2760,7 @@ pub extern "C" fn wr_dp_define_scroll_layer(
scroll_offset.to_vector(),
);
WrSpaceAndClip::from_webrender(space_and_clip)
WrSpatialId::from_webrender(space_and_clip)
}
#[no_mangle]
@ -2899,35 +2877,12 @@ pub extern "C" fn wr_dp_push_rect_with_animation(
}
#[no_mangle]
pub extern "C" fn wr_dp_push_rect_with_parent_clip(
state: &mut WrState,
rect: LayoutRect,
clip_rect: LayoutRect,
is_backface_visible: bool,
parent: &WrSpaceAndClip,
color: ColorF,
) {
debug_assert!(unsafe { !is_in_render_thread() });
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
flags: prim_flags(is_backface_visible, /* prefer_compositor_surface */ false),
};
state.frame_builder.dl_builder.push_rect(&prim_info, rect, color);
}
#[no_mangle]
pub extern "C" fn wr_dp_push_backdrop_filter_with_parent_clip(
pub extern "C" fn wr_dp_push_backdrop_filter(
state: &mut WrState,
rect: LayoutRect,
clip: LayoutRect,
is_backface_visible: bool,
parent: &WrSpaceAndClip,
parent: &WrSpaceAndClipChain,
filters: *const FilterOp,
filter_count: usize,
filter_datas: *const WrFilterData,
@ -3917,6 +3872,12 @@ impl WrSpatialId {
fn to_webrender(&self, pipeline_id: WrPipelineId) -> SpatialId {
SpatialId::new(self.id, pipeline_id)
}
fn from_webrender(id: SpatialId) -> Self {
WrSpatialId {
id: id.0,
}
}
}
#[no_mangle]

View File

@ -54,14 +54,18 @@ impl Example for App {
PrimitiveFlags::IS_BACKFACE_VISIBLE,
);
// set the scrolling clip
let space_and_clip1 = builder.define_scroll_frame(
&root_space_and_clip,
let space1 = builder.define_scroll_frame(
root_space_and_clip.spatial_id,
ExternalScrollId(EXT_SCROLL_ID_ROOT, PipelineId::dummy()),
(0, 0).by(1000, 1000),
scrollbox,
ScrollSensitivity::ScriptAndInputEvents,
LayoutVector2D::zero(),
);
let space_and_clip1 = SpaceAndClipInfo {
spatial_id: space1,
clip_id: root_space_and_clip.clip_id,
};
// now put some content into it.
// start with a white background
@ -86,14 +90,18 @@ impl Example for App {
// Below the above rectangles, set up a nested scrollbox. It's still in
// the same stacking context, so note that the rects passed in need to
// be relative to the stacking context.
let space_and_clip2 = builder.define_scroll_frame(
&space_and_clip1,
let space2 = builder.define_scroll_frame(
space1,
ExternalScrollId(EXT_SCROLL_ID_CONTENT, PipelineId::dummy()),
(0, 100).to(300, 1000),
(0, 100).to(200, 300),
ScrollSensitivity::ScriptAndInputEvents,
LayoutVector2D::zero(),
);
let space_and_clip2 = SpaceAndClipInfo {
spatial_id: space2,
clip_id: root_space_and_clip.clip_id,
};
// give it a giant gray background just to distinguish it and to easily
// visually identify the nested scrollbox

View File

@ -885,21 +885,12 @@ impl<'a> SceneBuilder<'a> {
pipeline_id: PipelineId,
) {
let current_offset = self.current_offset(parent_node_index);
let clip_rect = info.clip_rect.translate(current_offset);
// Just use clip rectangle as the frame rect for this scroll frame.
// This is useful when calculating scroll extents for the
// SpatialNode::scroll(..) API as well as for properly setting sticky
// positioning offsets.
let frame_rect = clip_rect;
let frame_rect = info.frame_rect.translate(current_offset);
let content_size = info.content_rect.size();
self.add_rect_clip_node(
info.clip_id,
&info.parent_space_and_clip,
&clip_rect,
);
self.add_scroll_frame(
info.scroll_frame_id,
parent_node_index,
@ -1523,7 +1514,7 @@ impl<'a> SceneBuilder<'a> {
DisplayItem::ScrollFrame(ref info) => {
profile_scope!("scrollframe");
let parent_space = self.get_space(info.parent_space_and_clip.spatial_id);
let parent_space = self.get_space(info.parent_space);
self.build_scroll_frame(
info,
parent_space,

View File

@ -298,15 +298,13 @@ pub enum ScrollSensitivity {
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
pub struct ScrollFrameDisplayItem {
/// The id of the clip this scroll frame creates
pub clip_id: ClipId,
/// 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).
// FIXME: this can *probably* just be a size? Origin seems to just get thrown out.
pub content_rect: LayoutRect,
pub clip_rect: LayoutRect,
pub parent_space_and_clip: SpaceAndClipInfo,
pub frame_rect: LayoutRect,
pub parent_space: SpatialId,
pub external_id: ExternalScrollId,
pub scroll_sensitivity: ScrollSensitivity,
/// The amount this scrollframe has already been scrolled by, in the caller.

View File

@ -1752,20 +1752,18 @@ impl DisplayListBuilder {
pub fn define_scroll_frame(
&mut self,
parent_space_and_clip: &di::SpaceAndClipInfo,
parent_space: di::SpatialId,
external_id: di::ExternalScrollId,
content_rect: LayoutRect,
clip_rect: LayoutRect,
frame_rect: LayoutRect,
scroll_sensitivity: di::ScrollSensitivity,
external_scroll_offset: LayoutVector2D,
) -> di::SpaceAndClipInfo {
let clip_id = self.generate_clip_index();
) -> di::SpatialId {
let scroll_frame_id = self.generate_spatial_index();
let item = di::DisplayItem::ScrollFrame(di::ScrollFrameDisplayItem {
content_rect,
clip_rect,
parent_space_and_clip: *parent_space_and_clip,
clip_id,
frame_rect,
parent_space,
scroll_frame_id,
external_id,
scroll_sensitivity,
@ -1774,10 +1772,7 @@ impl DisplayListBuilder {
self.push_item(&item);
di::SpaceAndClipInfo {
spatial_id: scroll_frame_id,
clip_id,
}
scroll_frame_id
}
pub fn define_clip_chain<I>(

View File

@ -4,6 +4,7 @@ root:
- type: scroll-frame
bounds: [9, 9, 10, 10]
content-size: [95, 88]
clip-to-frame: true
items:
- type: scroll-frame
bounds: [0, 0, 100, 100]

View File

@ -9,6 +9,7 @@ root:
bounds: [100, 100, 100, 100]
content-size: [260, 260]
scroll-offset: [0, 60]
clip-to-frame: true
items:
- type: rect
color: green

View File

@ -3,6 +3,7 @@ root:
- type: scroll-frame
bounds: [10, 10, 50, 50]
content-size: [100, 100]
clip-to-frame: true
items:
- type: rect
bounds: [10, 10, 500, 500]
@ -10,6 +11,7 @@ root:
- type: scroll-frame
bounds: [70, 10, 50, 50]
content-size: [100, 100]
clip-to-frame: true
items:
- type: rect
bounds: [70, 10, 100, 100]

View File

@ -10,6 +10,7 @@ root:
bounds: [10, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [10, 10, 50, 50]
@ -26,6 +27,7 @@ root:
bounds: [10, 70, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [10, 70, 50, 50]
@ -43,6 +45,7 @@ root:
bounds: [10, 130, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 40]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [10, 130, 50, 50]
@ -60,6 +63,7 @@ root:
bounds: [10, 190, 50, 50]
content-size: [200, 200]
scroll-offset: [0, -10]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [10, 190, 50, 50]
@ -76,6 +80,7 @@ root:
bounds: [10, 250, 50, 50]
content-size: [200, 200]
scroll-offset: [0, -10]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [10, 250, 50, 50]
@ -93,6 +98,7 @@ root:
bounds: [70, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [0, -50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [70, 10, 50, 50]
@ -107,6 +113,7 @@ root:
bounds: [70, 70, 50, 50]
content-size: [200, 200]
scroll-offset: [0, -50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [70, 70, 50, 50]
@ -121,6 +128,7 @@ root:
bounds: [70, 130, 50, 50]
content-size: [200, 200]
scroll-offset: [0, -40]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [70, 130, 50, 50]
@ -135,6 +143,7 @@ root:
bounds: [70, 190, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 10]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [70, 190, 50, 50]
@ -149,6 +158,7 @@ root:
bounds: [70, 250, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 10]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [70, 250, 50, 50]
@ -166,6 +176,7 @@ root:
bounds: [130, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [50, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [130, 10, 50, 50]
@ -180,6 +191,7 @@ root:
bounds: [130, 70, 50, 50]
content-size: [200, 200]
scroll-offset: [50, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [130, 70, 50, 50]
@ -194,6 +206,7 @@ root:
bounds: [130, 130, 50, 50]
content-size: [200, 200]
scroll-offset: [40, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [130, 130, 50, 50]
@ -208,6 +221,7 @@ root:
bounds: [130, 190, 50, 50]
content-size: [200, 200]
scroll-offset: [-10, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [130, 190, 50, 50]
@ -222,6 +236,7 @@ root:
bounds: [130, 250, 50, 50]
content-size: [200, 200]
scroll-offset: [-10, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [130, 250, 50, 50]
@ -239,6 +254,7 @@ root:
bounds: [190, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [-50, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [190, 10, 50, 50]
@ -253,6 +269,7 @@ root:
bounds: [190, 70, 50, 50]
content-size: [200, 200]
scroll-offset: [-50, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [190, 70, 50, 50]
@ -267,6 +284,7 @@ root:
bounds: [190, 130, 50, 50]
content-size: [200, 200]
scroll-offset: [-40, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [190, 130, 50, 50]
@ -281,6 +299,7 @@ root:
bounds: [190, 190, 50, 50]
content-size: [200, 200]
scroll-offset: [10, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [190, 190, 50, 50]
@ -295,6 +314,7 @@ root:
bounds: [190, 250, 50, 50]
content-size: [200, 200]
scroll-offset: [10, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [190, 250, 50, 50]

View File

@ -5,6 +5,7 @@ root:
- type: scroll-frame
bounds: [10, 10, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [10, 60, 50, 50]
@ -23,6 +24,7 @@ root:
bounds: [70, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [70, 10, 50, 50]
@ -40,6 +42,7 @@ root:
- type: scroll-frame
bounds: [10, 70, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [60, 70, 50, 50]
@ -58,6 +61,7 @@ root:
bounds: [70, 70, 50, 50]
content-size: [200, 200]
scroll-offset: [50, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [70, 70, 50, 50]
@ -76,6 +80,7 @@ root:
- type: scroll-frame
bounds: [130, 10, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [130, 60, 50, 50]
@ -94,6 +99,7 @@ root:
bounds: [190, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [190, 10, 50, 50]
@ -111,6 +117,7 @@ root:
- type: scroll-frame
bounds: [130, 70, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [180, 70, 50, 50]
@ -129,6 +136,7 @@ root:
bounds: [190, 70, 50, 50]
content-size: [200, 200]
scroll-offset: [50, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [190, 70, 50, 50]
@ -147,6 +155,7 @@ root:
- type: scroll-frame
bounds: [250, 10, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [250, 60, 50, 50]
@ -165,6 +174,7 @@ root:
bounds: [310, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [310, 10, 50, 50]
@ -182,6 +192,7 @@ root:
- type: scroll-frame
bounds: [250, 70, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [300, 70, 50, 50]
@ -200,6 +211,7 @@ root:
bounds: [310, 70, 50, 50]
content-size: [200, 200]
scroll-offset: [50, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [310, 70, 50, 50]

View File

@ -5,6 +5,7 @@ root:
- type: scroll-frame
bounds: [10, 10, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [10, 60, 50, 50]
@ -19,6 +20,7 @@ root:
bounds: [70, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [70, 10, 50, 50]
@ -32,6 +34,7 @@ root:
- type: scroll-frame
bounds: [10, 70, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [60, 70, 50, 50]
@ -46,6 +49,7 @@ root:
bounds: [70, 70, 50, 50]
content-size: [200, 200]
scroll-offset: [50, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [70, 70, 50, 50]
@ -60,6 +64,7 @@ root:
- type: scroll-frame
bounds: [130, 10, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [130, 60, 50, 50]
@ -74,6 +79,7 @@ root:
bounds: [190, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [190, 10, 50, 50]
@ -87,6 +93,7 @@ root:
- type: scroll-frame
bounds: [130, 70, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [180, 70, 50, 50]
@ -101,6 +108,7 @@ root:
bounds: [190, 70, 50, 50]
content-size: [200, 200]
scroll-offset: [50, 0]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [190, 70, 50, 50]
@ -115,6 +123,7 @@ root:
- type: scroll-frame
bounds: [250, 10, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [250, 60, 50, 50]
@ -129,6 +138,7 @@ root:
bounds: [310, 10, 50, 50]
content-size: [200, 200]
scroll-offset: [0, 50]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [310, 10, 50, 50]
@ -142,6 +152,7 @@ root:
- type: scroll-frame
bounds: [250, 70, 50, 50]
content-size: [200, 200]
clip-to-frame: true
items:
- type: sticky-frame
bounds: [300, 70, 50, 50]
@ -155,6 +166,7 @@ root:
- type: scroll-frame
bounds: [310, 70, 50, 50]
content-size: [200, 200]
clip-to-frame: true
scroll-offset: [50, 0]
items:
- type: sticky-frame

View File

@ -9,6 +9,7 @@ root:
items:
- type: scroll-frame
bounds: 0 0 1000 1000
clip-to-frame: true
items:
- type: sticky-frame
bounds: 0 -50 1000 50

View File

@ -5,6 +5,7 @@ root:
- type: scroll-frame
bounds: [0, 0, 500, 200]
content-size: [500, 500]
clip-to-frame: true
id: 2
items:
- type: rect

View File

@ -19,6 +19,7 @@ pipelines:
type: "scroll-frame"
id: 2
bounds: [0, 0, 1887, 1971]
clip-to-frame: true
-
"clip-and-scroll": 2
type: "stacking-context"

View File

@ -6,6 +6,7 @@ root:
id: 2
"content-size": [500, 100]
bounds: [0, 0, 500, 100]
clip-to-frame: true
items:
-
type: "stacking-context"

View File

@ -1823,8 +1823,19 @@ impl YamlFrameReader {
self.scroll_offsets.insert(external_id, LayoutPoint::new(size.x, size.y));
}
let space_and_clip = dl.define_scroll_frame(
&self.top_space_and_clip(),
let clip_to_frame = yaml["clip-to-frame"].as_bool().unwrap_or(false);
let clip_id = if clip_to_frame {
Some(dl.define_clip_rect(
&self.top_space_and_clip(),
clip_rect,
))
} else {
None
};
let spatial_id = dl.define_scroll_frame(
self.top_space_and_clip().spatial_id,
external_id,
content_rect,
clip_rect,
@ -1832,15 +1843,21 @@ impl YamlFrameReader {
external_scroll_offset,
);
if let Some(numeric_id) = numeric_id {
self.add_spatial_id_mapping(numeric_id, space_and_clip.spatial_id);
self.add_clip_id_mapping(numeric_id, space_and_clip.clip_id);
self.add_spatial_id_mapping(numeric_id, spatial_id);
if let Some(clip_id) = clip_id {
self.add_clip_id_mapping(numeric_id, clip_id);
}
}
if !yaml["items"].is_badvalue() {
self.spatial_id_stack.push(space_and_clip.spatial_id);
self.clip_id_stack.push(space_and_clip.clip_id);
self.spatial_id_stack.push(spatial_id);
if let Some(clip_id) = clip_id {
self.clip_id_stack.push(clip_id);
}
self.add_display_list_items_from_yaml(dl, wrench, &yaml["items"]);
self.clip_id_stack.pop().unwrap();
if let Some(_) = clip_id {
self.clip_id_stack.pop().unwrap();
}
self.spatial_id_stack.pop().unwrap();
}
}