зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1395212 - Hoist the scroll layer deduplication code out of bindings.rs into wr::DisplayListBuilder. r=mstange
This also splits the wr_dp_push_scroll_layer function in bindings.rs into two separate functions. This makes the API consistent with clipping, and also allows for optimizations in the upcoming patches. MozReview-Commit-ID: IXnOZK0dZm --HG-- extra : rebase_source : aa28875433a03ee9d6c388750f022958958d05e9
This commit is contained in:
Родитель
07880c5a6c
Коммит
b8355b02c7
|
@ -177,7 +177,7 @@ ScrollingLayersHelper::DefineAndPushScrollLayers(nsDisplayItem* aItem,
|
||||||
DefineAndPushChain(asrClippedBy, aBuilder, aStackingContext,
|
DefineAndPushChain(asrClippedBy, aBuilder, aStackingContext,
|
||||||
aAppUnitsPerDevPixel, aCache);
|
aAppUnitsPerDevPixel, aCache);
|
||||||
// Finally, push the ASR itself as a scroll layer. Note that the
|
// Finally, push the ASR itself as a scroll layer. Note that the
|
||||||
// implementation of wr_push_scroll_layer in bindings.rs makes sure the
|
// implementation of PushScrollLayer in DisplayListBuilder makes sure the
|
||||||
// scroll layer doesn't get defined multiple times so we don't need to worry
|
// scroll layer doesn't get defined multiple times so we don't need to worry
|
||||||
// about that here.
|
// about that here.
|
||||||
if (PushScrollLayer(metadata->GetMetrics(), aStackingContext)) {
|
if (PushScrollLayer(metadata->GetMetrics(), aStackingContext)) {
|
||||||
|
|
|
@ -685,14 +685,21 @@ DisplayListBuilder::PushScrollLayer(const layers::FrameMetrics::ViewID& aScrollI
|
||||||
{
|
{
|
||||||
WRDL_LOG("PushScrollLayer id=%" PRIu64 " co=%s cl=%s\n", mWrState,
|
WRDL_LOG("PushScrollLayer id=%" PRIu64 " co=%s cl=%s\n", mWrState,
|
||||||
aScrollId, Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
|
aScrollId, Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
|
||||||
wr_dp_push_scroll_layer(mWrState, aScrollId, aContentRect, aClipRect);
|
|
||||||
if (!mScrollIdStack.empty()) {
|
Maybe<layers::FrameMetrics::ViewID> parent =
|
||||||
auto it = mScrollParents.insert({aScrollId, mScrollIdStack.back()});
|
mScrollIdStack.empty() ? Nothing() : Some(mScrollIdStack.back());
|
||||||
if (!it.second) { // aScrollId was already a key in mScrollParents
|
auto it = mScrollParents.insert({aScrollId, parent});
|
||||||
// so check that the parent value is the same.
|
if (it.second) {
|
||||||
MOZ_ASSERT(it.first->second == mScrollIdStack.back());
|
// 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);
|
||||||
|
} else {
|
||||||
|
// aScrollId was already a key in mScrollParents so check that the parent
|
||||||
|
// value is the same.
|
||||||
|
MOZ_ASSERT(it.first->second == parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wr_dp_push_scroll_layer(mWrState, aScrollId);
|
||||||
mScrollIdStack.push_back(aScrollId);
|
mScrollIdStack.push_back(aScrollId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1011,7 +1018,7 @@ Maybe<layers::FrameMetrics::ViewID>
|
||||||
DisplayListBuilder::ParentScrollIdFor(layers::FrameMetrics::ViewID aScrollId)
|
DisplayListBuilder::ParentScrollIdFor(layers::FrameMetrics::ViewID aScrollId)
|
||||||
{
|
{
|
||||||
auto it = mScrollParents.find(aScrollId);
|
auto it = mScrollParents.find(aScrollId);
|
||||||
return (it == mScrollParents.end() ? Nothing() : Some(it->second));
|
return (it == mScrollParents.end() ? Nothing() : it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace wr
|
} // namespace wr
|
||||||
|
|
|
@ -348,8 +348,10 @@ protected:
|
||||||
std::vector<wr::WrClipId> mClipIdStack;
|
std::vector<wr::WrClipId> mClipIdStack;
|
||||||
std::vector<layers::FrameMetrics::ViewID> mScrollIdStack;
|
std::vector<layers::FrameMetrics::ViewID> mScrollIdStack;
|
||||||
|
|
||||||
// Track the parent scroll id of each scroll id that we encountered.
|
// Track the parent scroll id of each scroll id that we encountered. A
|
||||||
std::unordered_map<layers::FrameMetrics::ViewID, layers::FrameMetrics::ViewID> mScrollParents;
|
// Nothing() value indicates a root scroll id. We also use this structure to
|
||||||
|
// ensure that we don't define a particular scroll layer multiple times.
|
||||||
|
std::unordered_map<layers::FrameMetrics::ViewID, Maybe<layers::FrameMetrics::ViewID>> mScrollParents;
|
||||||
|
|
||||||
friend class WebRenderAPI;
|
friend class WebRenderAPI;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::collections::HashSet;
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::{mem, slice};
|
use std::{mem, slice};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -926,7 +925,6 @@ pub unsafe extern "C" fn wr_api_get_namespace(dh: &mut DocumentHandle) -> WrIdNa
|
||||||
pub struct WebRenderFrameBuilder {
|
pub struct WebRenderFrameBuilder {
|
||||||
pub root_pipeline_id: WrPipelineId,
|
pub root_pipeline_id: WrPipelineId,
|
||||||
pub dl_builder: webrender_api::DisplayListBuilder,
|
pub dl_builder: webrender_api::DisplayListBuilder,
|
||||||
pub scroll_clips_defined: HashSet<ClipId>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebRenderFrameBuilder {
|
impl WebRenderFrameBuilder {
|
||||||
|
@ -935,7 +933,6 @@ impl WebRenderFrameBuilder {
|
||||||
WebRenderFrameBuilder {
|
WebRenderFrameBuilder {
|
||||||
root_pipeline_id: root_pipeline_id,
|
root_pipeline_id: root_pipeline_id,
|
||||||
dl_builder: webrender_api::DisplayListBuilder::new(root_pipeline_id, content_size),
|
dl_builder: webrender_api::DisplayListBuilder::new(root_pipeline_id, content_size),
|
||||||
scroll_clips_defined: HashSet::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1102,21 +1099,22 @@ pub extern "C" fn wr_dp_pop_clip(state: &mut WrState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wr_dp_push_scroll_layer(state: &mut WrState,
|
pub extern "C" fn wr_dp_define_scroll_layer(state: &mut WrState,
|
||||||
scroll_id: u64,
|
scroll_id: u64,
|
||||||
content_rect: LayoutRect,
|
content_rect: LayoutRect,
|
||||||
clip_rect: LayoutRect) {
|
clip_rect: LayoutRect) {
|
||||||
assert!(unsafe { is_in_main_thread() });
|
assert!(unsafe { is_in_main_thread() });
|
||||||
let clip_id = ClipId::new(scroll_id, state.pipeline_id);
|
let clip_id = ClipId::new(scroll_id, state.pipeline_id);
|
||||||
// Avoid defining multiple scroll clips with the same clip id, as that
|
state.frame_builder.dl_builder.define_scroll_frame(
|
||||||
// results in undefined behaviour or assertion failures.
|
Some(clip_id), content_rect, clip_rect, vec![], None,
|
||||||
if !state.frame_builder.scroll_clips_defined.contains(&clip_id) {
|
ScrollSensitivity::Script);
|
||||||
|
}
|
||||||
|
|
||||||
state.frame_builder.dl_builder.define_scroll_frame(
|
#[no_mangle]
|
||||||
Some(clip_id), content_rect, clip_rect, vec![], None,
|
pub extern "C" fn wr_dp_push_scroll_layer(state: &mut WrState,
|
||||||
ScrollSensitivity::Script);
|
scroll_id: u64) {
|
||||||
state.frame_builder.scroll_clips_defined.insert(clip_id);
|
assert!(unsafe { is_in_main_thread() });
|
||||||
}
|
let clip_id = ClipId::new(scroll_id, state.pipeline_id);
|
||||||
state.frame_builder.dl_builder.push_clip_id(clip_id);
|
state.frame_builder.dl_builder.push_clip_id(clip_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -860,6 +860,13 @@ uint64_t wr_dp_define_clip(WrState *aState,
|
||||||
const WrImageMask *aMask)
|
const WrImageMask *aMask)
|
||||||
WR_FUNC;
|
WR_FUNC;
|
||||||
|
|
||||||
|
WR_INLINE
|
||||||
|
void wr_dp_define_scroll_layer(WrState *aState,
|
||||||
|
uint64_t aScrollId,
|
||||||
|
LayoutRect aContentRect,
|
||||||
|
LayoutRect aClipRect)
|
||||||
|
WR_FUNC;
|
||||||
|
|
||||||
WR_INLINE
|
WR_INLINE
|
||||||
void wr_dp_end(WrState *aState)
|
void wr_dp_end(WrState *aState)
|
||||||
WR_FUNC;
|
WR_FUNC;
|
||||||
|
@ -1027,9 +1034,7 @@ WR_FUNC;
|
||||||
|
|
||||||
WR_INLINE
|
WR_INLINE
|
||||||
void wr_dp_push_scroll_layer(WrState *aState,
|
void wr_dp_push_scroll_layer(WrState *aState,
|
||||||
uint64_t aScrollId,
|
uint64_t aScrollId)
|
||||||
LayoutRect aContentRect,
|
|
||||||
LayoutRect aClipRect)
|
|
||||||
WR_FUNC;
|
WR_FUNC;
|
||||||
|
|
||||||
WR_INLINE
|
WR_INLINE
|
||||||
|
|
Загрузка…
Ссылка в новой задаче