Bug 1409446 - Wire up the DefineClip and DefineScrollLayer APIs to allow specifying ancestry. r=jrmuizel

The APIs now allow providing the parent clip or scroll info explicitly
instead of having to push it on the stack. For now we just pass
Nothing() to preserve the existing behaviour, so this change is a
functinoal no-op.

MozReview-Commit-ID: dtNamN595

--HG--
extra : rebase_source : 3b6bd03b919bd31cd89e3f82283cb962f8f6abc5
This commit is contained in:
Kartikaya Gupta 2017-10-24 15:45:57 -04:00
Родитель d14980c3ad
Коммит 2878061467
7 изменённых файлов: 94 добавлений и 25 удалений

Просмотреть файл

@ -157,7 +157,7 @@ ScrollingLayersHelper::DefineAndPushChain(const DisplayItemClipChain* aChain,
aChain->mClip.GetClipRect(), aAppUnitsPerDevPixel);
nsTArray<wr::ComplexClipRegion> wrRoundedRects;
aChain->mClip.ToComplexClipRegions(aAppUnitsPerDevPixel, aStackingContext, wrRoundedRects);
clipId = Some(aBuilder.DefineClip(aStackingContext.ToRelativeLayoutRect(clip), &wrRoundedRects));
clipId = Some(aBuilder.DefineClip(Nothing(), Nothing(), aStackingContext.ToRelativeLayoutRect(clip), &wrRoundedRects));
if (!aBuilder.HasExtraClip()) {
aCache[aChain] = clipId.value();
}
@ -190,7 +190,7 @@ ScrollingLayersHelper::DefineAndPushScrollLayer(const FrameMetrics& aMetrics,
// WebRender at all. Instead, we take the position from the composition
// bounds.
contentRect.MoveTo(clipBounds.TopLeft());
mBuilder->DefineScrollLayer(aMetrics.GetScrollId(),
mBuilder->DefineScrollLayer(aMetrics.GetScrollId(), Nothing(), Nothing(),
aStackingContext.ToRelativeLayoutRect(contentRect),
aStackingContext.ToRelativeLayoutRect(clipBounds));
mBuilder->PushScrollLayer(aMetrics.GetScrollId());

Просмотреть файл

@ -693,16 +693,27 @@ DisplayListBuilder::PopStackingContext()
}
wr::WrClipId
DisplayListBuilder::DefineClip(const wr::LayoutRect& aClipRect,
DisplayListBuilder::DefineClip(const Maybe<layers::FrameMetrics::ViewID>& aAncestorScrollId,
const Maybe<wr::WrClipId>& aAncestorClipId,
const wr::LayoutRect& aClipRect,
const nsTArray<wr::ComplexClipRegion>* aComplex,
const wr::WrImageMask* aMask)
{
uint64_t clip_id = wr_dp_define_clip(mWrState, aClipRect,
const uint64_t* ancestorClipId = nullptr;
if (aAncestorClipId) {
ancestorClipId = &(aAncestorClipId.ref().id);
}
uint64_t clip_id = wr_dp_define_clip(mWrState,
aAncestorScrollId.ptrOr(nullptr), ancestorClipId,
aClipRect,
aComplex ? aComplex->Elements() : nullptr,
aComplex ? aComplex->Length() : 0,
aMask);
WRDL_LOG("DefineClip id=%" PRIu64 " r=%s m=%p b=%s complex=%zu\n", mWrState,
clip_id, Stringify(aClipRect).c_str(), aMask,
WRDL_LOG("DefineClip id=%" PRIu64 " as=%s ac=%s r=%s m=%p b=%s complex=%zu\n", mWrState,
clip_id,
aAncestorScrollId ? Stringify(aAncestorScrollId.ref()).c_str() : "(nil)",
aAncestorClipId ? Stringify(aAncestorClipId.ref().id).c_str() : "(nil)",
Stringify(aClipRect).c_str(), aMask,
aMask ? Stringify(aMask->rect).c_str() : "none",
aComplex ? aComplex->Length() : 0);
return wr::WrClipId { clip_id };
@ -772,11 +783,16 @@ DisplayListBuilder::IsScrollLayerDefined(layers::FrameMetrics::ViewID aScrollId)
void
DisplayListBuilder::DefineScrollLayer(const layers::FrameMetrics::ViewID& aScrollId,
const Maybe<layers::FrameMetrics::ViewID>& aAncestorScrollId,
const Maybe<wr::WrClipId>& aAncestorClipId,
const wr::LayoutRect& aContentRect,
const wr::LayoutRect& aClipRect)
{
WRDL_LOG("DefineScrollLayer id=%" PRIu64 " co=%s cl=%s\n", mWrState,
aScrollId, Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
WRDL_LOG("DefineScrollLayer id=%" PRIu64 " as=%s ac=%s co=%s cl=%s\n", mWrState,
aScrollId,
aAncestorScrollId ? Stringify(aAncestorScrollId.ref()).c_str() : "(nil)",
aAncestorClipId ? Stringify(aAncestorClipId.ref().id).c_str() : "(nil)",
Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
Maybe<layers::FrameMetrics::ViewID> parent =
mScrollIdStack.empty() ? Nothing() : Some(mScrollIdStack.back());
@ -784,7 +800,12 @@ DisplayListBuilder::DefineScrollLayer(const layers::FrameMetrics::ViewID& aScrol
if (it.second) {
// An insertion took place, which means we haven't defined aScrollId before.
// So let's define it now.
wr_dp_define_scroll_layer(mWrState, aScrollId, aContentRect, aClipRect);
const uint64_t* ancestorClipId = nullptr;
if (aAncestorClipId) {
ancestorClipId = &(aAncestorClipId.ref().id);
}
wr_dp_define_scroll_layer(mWrState, aScrollId, aAncestorScrollId.ptrOr(nullptr),
ancestorClipId, aContentRect, aClipRect);
} else {
// aScrollId was already a key in mScrollParents so check that the parent
// value is the same.

Просмотреть файл

@ -228,7 +228,9 @@ public:
bool aIsBackfaceVisible);
void PopStackingContext();
wr::WrClipId DefineClip(const wr::LayoutRect& aClipRect,
wr::WrClipId DefineClip(const Maybe<layers::FrameMetrics::ViewID>& aAncestorScrollId,
const Maybe<wr::WrClipId>& aAncestorClipId,
const wr::LayoutRect& aClipRect,
const nsTArray<wr::ComplexClipRegion>* aComplex = nullptr,
const wr::WrImageMask* aMask = nullptr);
void PushClip(const wr::WrClipId& aClipId, bool aExtra = false);
@ -244,6 +246,8 @@ public:
bool IsScrollLayerDefined(layers::FrameMetrics::ViewID aScrollId) const;
void DefineScrollLayer(const layers::FrameMetrics::ViewID& aScrollId,
const Maybe<layers::FrameMetrics::ViewID>& aAncestorScrollId,
const Maybe<wr::WrClipId>& aAncestorClipId,
const wr::LayoutRect& aContentRect, // TODO: We should work with strongly typed rects
const wr::LayoutRect& aClipRect);
void PushScrollLayer(const layers::FrameMetrics::ViewID& aScrollId);

Просмотреть файл

@ -1205,19 +1205,52 @@ pub extern "C" fn wr_dp_pop_stacking_context(state: &mut WrState) {
state.frame_builder.dl_builder.pop_stacking_context();
}
fn make_scroll_info(state: &mut WrState,
scroll_id: Option<&u64>,
clip_id: Option<&u64>)
-> Option<ClipAndScrollInfo> {
if let Some(&sid) = scroll_id {
if let Some(&cid) = clip_id {
Some(ClipAndScrollInfo::new(
ClipId::new(sid, state.pipeline_id),
ClipId::Clip(cid, state.pipeline_id)))
} else {
Some(ClipAndScrollInfo::simple(
ClipId::new(sid, state.pipeline_id)))
}
} else if let Some(&cid) = clip_id {
Some(ClipAndScrollInfo::simple(
ClipId::Clip(cid, state.pipeline_id)))
} else {
None
}
}
#[no_mangle]
pub extern "C" fn wr_dp_define_clip(state: &mut WrState,
ancestor_scroll_id: *const u64,
ancestor_clip_id: *const u64,
clip_rect: LayoutRect,
complex: *const ComplexClipRegion,
complex_count: usize,
mask: *const WrImageMask)
-> u64 {
debug_assert!(unsafe { is_in_main_thread() });
let info = make_scroll_info(state,
unsafe { ancestor_scroll_id.as_ref() },
unsafe { ancestor_clip_id.as_ref() });
let complex_slice = make_slice(complex, complex_count);
let complex_iter = complex_slice.iter().cloned();
let mask : Option<ImageMask> = unsafe { mask.as_ref() }.map(|x| x.into());
let clip_id = state.frame_builder.dl_builder.define_clip(None, clip_rect, complex_iter, mask);
let clip_id = if info.is_some() {
state.frame_builder.dl_builder.define_clip_with_parent(None,
info.unwrap().scroll_node_id, clip_rect, complex_iter, mask)
} else {
state.frame_builder.dl_builder.define_clip(None, clip_rect, complex_iter, mask)
};
// return the u64 id value from inside the ClipId::Clip(..)
match clip_id {
ClipId::Clip(id, pipeline_id) => {
@ -1268,13 +1301,26 @@ pub extern "C" fn wr_dp_define_sticky_frame(state: &mut WrState,
#[no_mangle]
pub extern "C" fn wr_dp_define_scroll_layer(state: &mut WrState,
scroll_id: u64,
ancestor_scroll_id: *const u64,
ancestor_clip_id: *const u64,
content_rect: LayoutRect,
clip_rect: LayoutRect) {
assert!(unsafe { is_in_main_thread() });
let info = make_scroll_info(state,
unsafe { ancestor_scroll_id.as_ref() },
unsafe { ancestor_clip_id.as_ref() });
let clip_id = ClipId::new(scroll_id, state.pipeline_id);
state.frame_builder.dl_builder.define_scroll_frame(
Some(clip_id), content_rect, clip_rect, vec![], None,
ScrollSensitivity::Script);
if info.is_some() {
state.frame_builder.dl_builder.define_scroll_frame_with_parent(
Some(clip_id), info.unwrap().scroll_node_id, content_rect,
clip_rect, vec![], None, ScrollSensitivity::Script);
} else {
state.frame_builder.dl_builder.define_scroll_frame(
Some(clip_id), content_rect, clip_rect, vec![], None,
ScrollSensitivity::Script);
};
}
#[no_mangle]
@ -1306,15 +1352,9 @@ pub extern "C" fn wr_dp_push_clip_and_scroll_info(state: &mut WrState,
scroll_id: u64,
clip_id: *const u64) {
debug_assert!(unsafe { is_in_main_thread() });
let scroll_id = ClipId::new(scroll_id, state.pipeline_id);
let info = if let Some(&id) = unsafe { clip_id.as_ref() } {
ClipAndScrollInfo::new(
scroll_id,
ClipId::Clip(id, state.pipeline_id))
} else {
ClipAndScrollInfo::simple(scroll_id)
};
state.frame_builder.dl_builder.push_clip_and_scroll_info(info);
let info = make_scroll_info(state, Some(&scroll_id), unsafe { clip_id.as_ref() });
debug_assert!(info.is_some());
state.frame_builder.dl_builder.push_clip_and_scroll_info(info.unwrap());
}
#[no_mangle]

Просмотреть файл

@ -947,6 +947,8 @@ WR_FUNC;
WR_INLINE
uint64_t wr_dp_define_clip(WrState *aState,
const uint64_t *aAncestorScrollId,
const uint64_t *aAncestorClipId,
LayoutRect aClipRect,
const ComplexClipRegion *aComplex,
size_t aComplexCount,
@ -956,6 +958,8 @@ WR_FUNC;
WR_INLINE
void wr_dp_define_scroll_layer(WrState *aState,
uint64_t aScrollId,
const uint64_t *aAncestorScrollId,
const uint64_t *aAncestorClipId,
LayoutRect aContentRect,
LayoutRect aClipRect)
WR_FUNC;

Просмотреть файл

@ -3621,7 +3621,7 @@ nsCSSBorderRenderer::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
if (mLocalClip) {
LayoutDeviceRect clip = LayoutDeviceRect::FromUnknownRect(mLocalClip.value());
wr::LayoutRect clipRect = aSc.ToRelativeLayoutRect(clip);
wr::WrClipId clipId = aBuilder.DefineClip(clipRect);
wr::WrClipId clipId = aBuilder.DefineClip(Nothing(), Nothing(), clipRect);
aBuilder.PushClip(clipId, true);
}

Просмотреть файл

@ -9408,7 +9408,7 @@ nsDisplayMask::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder
aSc, aDisplayListBuilder,
bounds);
if (mask) {
wr::WrClipId clipId = aBuilder.DefineClip(
wr::WrClipId clipId = aBuilder.DefineClip(Nothing(), Nothing(),
aSc.ToRelativeLayoutRect(bounds), nullptr, mask.ptr());
// Don't record this clip push in aBuilder's internal clip stack, because
// otherwise any nested ScrollingLayersHelper instances that are created