Bug 1324965. Remove nested DisplayListBuilders. r=mchang?

This simplifies the logic around displaylist builders and
makes us push immediately instead of deferring it. The data
we used to pass to pop() is now passed to push().

This is also closer to what Servo does.

In a follow up I'll rename some of the methods to closer
align with the webrender names.
This commit is contained in:
Jeff Muizelaar 2016-12-21 13:36:31 -05:00
Родитель 4dbcec85a4
Коммит 34eabc2d62
9 изменённых файлов: 65 добавлений и 77 удалений

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

@ -20,15 +20,15 @@ using mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
namespace mozilla {
namespace layers {
struct OpPushDLBuilder { };
struct OpPopDLBuilder {
struct OpPushDLBuilder {
WRRect bounds;
WRRect overflow;
Matrix4x4 matrix;
uint64_t scrollid;
};
struct OpPopDLBuilder { };
struct OpDPPushRect {
WRRect bounds;
WRRect clip;

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

@ -270,13 +270,12 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
switch (cmd.type()) {
case WebRenderCommand::TOpPushDLBuilder: {
wr_push_dl_builder(mWRState);
const OpPushDLBuilder& op = cmd.get_OpPushDLBuilder();
wr_push_dl_builder(mWRState, op.bounds(), op.overflow(), &(op.matrix().components[0]));
break;
}
case WebRenderCommand::TOpPopDLBuilder: {
const OpPopDLBuilder& op = cmd.get_OpPopDLBuilder();
// XXX overflow is not used for now.
wr_pop_dl_builder(mWRState, op.bounds(), op.overflow(), &(op.matrix().components[0]));
wr_pop_dl_builder(mWRState);
break;
}
case WebRenderCommand::TOpDPPushRect: {

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

@ -111,15 +111,15 @@ WebRenderCanvasLayer::RenderLayer()
clip = rect;
}
if (gfxPrefs::LayersDump()) printf_stderr("CanvasLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
WRBridge()->AddWebRenderCommand(OpPushDLBuilder());
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
WRBridge()->AddWebRenderCommand(
OpPushDLBuilder(toWrRect(relBounds), toWrRect(overflow), transform, FrameMetrics::NULL_SCROLL_ID));
WRBridge()->AddWebRenderCommand(OpDPPushImage(toWrRect(rect), toWrRect(clip), Nothing(), key));
Manager()->AddImageKeyForDiscard(key);
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
if (gfxPrefs::LayersDump()) printf_stderr("CanvasLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
WRBridge()->AddWebRenderCommand(
OpPopDLBuilder(toWrRect(relBounds), toWrRect(overflow), transform, FrameMetrics::NULL_SCROLL_ID));
WRBridge()->AddWebRenderCommand(OpPopDLBuilder());
}
} // namespace layers

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

@ -23,12 +23,13 @@ WebRenderContainerLayer::RenderLayer()
gfx::Matrix4x4 transform;// = GetTransform();
if (gfxPrefs::LayersDump()) printf_stderr("ContainerLayer %p using %s as bounds/overflow, %s as transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
WRBridge()->AddWebRenderCommand(OpPushDLBuilder());
WRBridge()->AddWebRenderCommand(
OpPushDLBuilder(toWrRect(relBounds), toWrRect(relBounds), transform, FrameMetrics::NULL_SCROLL_ID));
for (LayerPolygon& child : children) {
ToWebRenderLayer(child.layer)->RenderLayer();
}
WRBridge()->AddWebRenderCommand(
OpPopDLBuilder(toWrRect(relBounds), toWrRect(relBounds), transform, FrameMetrics::NULL_SCROLL_ID));
OpPopDLBuilder());
}
void

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

@ -135,16 +135,17 @@ WebRenderImageLayer::RenderLayer()
clip = rect;
}
if (gfxPrefs::LayersDump()) printf_stderr("ImageLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
WRBridge()->AddWebRenderCommand(OpPushDLBuilder());
WRBridge()->AddWebRenderCommand(OpDPPushExternalImageId(toWrRect(rect), toWrRect(clip), Nothing(), mExternalImageId));
Rect relBounds = TransformedVisibleBoundsRelativeToParent();
Rect overflow(0, 0, relBounds.width, relBounds.height);
Matrix4x4 transform;// = GetTransform();
if (gfxPrefs::LayersDump()) printf_stderr("ImageLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
WRBridge()->AddWebRenderCommand(
OpPopDLBuilder(toWrRect(relBounds), toWrRect(overflow), transform, FrameMetrics::NULL_SCROLL_ID));
OpPushDLBuilder(toWrRect(relBounds), toWrRect(overflow), transform, FrameMetrics::NULL_SCROLL_ID));
WRBridge()->AddWebRenderCommand(OpDPPushExternalImageId(toWrRect(rect), toWrRect(clip), Nothing(), mExternalImageId));
if (gfxPrefs::LayersDump()) printf_stderr("ImageLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
WRBridge()->AddWebRenderCommand(OpPopDLBuilder());
//mContainer->SetImageFactory(originalIF);
}

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

@ -95,26 +95,13 @@ WRScrollFrameStackingContextGenerator::WRScrollFrameStackingContextGenerator(
WebRenderLayer* aLayer)
: mLayer(aLayer)
{
Matrix4x4 identity;
Layer* layer = mLayer->GetLayer();
for (size_t i = layer->GetScrollMetadataCount(); i > 0; i--) {
const FrameMetrics& fm = layer->GetFrameMetrics(i - 1);
if (!fm.IsScrollable()) {
continue;
}
if (gfxPrefs::LayersDump()) printf_stderr("Pushing stacking context id %" PRIu64"\n", fm.GetScrollId());
mLayer->WRBridge()->AddWebRenderCommand(OpPushDLBuilder());
}
}
WRScrollFrameStackingContextGenerator::~WRScrollFrameStackingContextGenerator()
{
Matrix4x4 identity;
Layer* layer = mLayer->GetLayer();
for (size_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
const FrameMetrics& fm = layer->GetFrameMetrics(i);
if (!fm.IsScrollable()) {
continue;
}
Rect bounds = fm.GetCompositionBounds().ToUnknownRect();
Rect overflow = (fm.GetExpandedScrollableRect() * fm.LayersPixelsPerCSSPixel()).ToUnknownRect();
Point scrollPos = (fm.GetScrollOffset() * fm.LayersPixelsPerCSSPixel()).ToUnknownPoint();
@ -126,11 +113,25 @@ WRScrollFrameStackingContextGenerator::~WRScrollFrameStackingContextGenerator()
// on the scroll offset, we'd fail those checks.
overflow.MoveBy(bounds.x - scrollPos.x, bounds.y - scrollPos.y);
if (gfxPrefs::LayersDump()) {
printf_stderr("Popping stacking context id %" PRIu64 " with bounds=%s overflow=%s\n",
printf_stderr("Pushing stacking context id %" PRIu64 " with bounds=%s overflow=%s\n",
fm.GetScrollId(), Stringify(bounds).c_str(), Stringify(overflow).c_str());
}
mLayer->WRBridge()->AddWebRenderCommand(
OpPopDLBuilder(toWrRect(bounds), toWrRect(overflow), identity, fm.GetScrollId()));
OpPushDLBuilder(toWrRect(bounds), toWrRect(overflow), identity, fm.GetScrollId()));
}
}
WRScrollFrameStackingContextGenerator::~WRScrollFrameStackingContextGenerator()
{
Layer* layer = mLayer->GetLayer();
for (size_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
const FrameMetrics& fm = layer->GetFrameMetrics(i);
if (!fm.IsScrollable()) {
continue;
}
if (gfxPrefs::LayersDump()) printf_stderr("Popping stacking context id %" PRIu64"\n", fm.GetScrollId());
mLayer->WRBridge()->AddWebRenderCommand(OpPopDLBuilder());
}
}

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

@ -26,7 +26,6 @@ WebRenderPaintedLayer::RenderLayer()
}
WRScrollFrameStackingContextGenerator scrollFrames(this);
WRBridge()->AddWebRenderCommand(OpPushDLBuilder());
RefPtr<DrawTarget> target = gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, size.ToUnknownSize(), SurfaceFormat::B8G8R8A8);
target->SetTransform(Matrix().PreTranslate(-bounds.x, -bounds.y));
@ -67,15 +66,18 @@ WebRenderPaintedLayer::RenderLayer()
clip = rect;
}
if (gfxPrefs::LayersDump()) printf_stderr("PaintedLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
WRBridge()->AddWebRenderCommand(OpDPPushImage(toWrRect(rect), toWrRect(clip), Nothing(), key));
Manager()->AddImageKeyForDiscard(key);
Rect relBounds = TransformedVisibleBoundsRelativeToParent();
Rect overflow(0, 0, relBounds.width, relBounds.height);
Matrix4x4 transform;// = GetTransform();
if (gfxPrefs::LayersDump()) printf_stderr("PaintedLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
WRBridge()->AddWebRenderCommand(
OpPopDLBuilder(toWrRect(relBounds), toWrRect(overflow), transform, FrameMetrics::NULL_SCROLL_ID));
OpPushDLBuilder(toWrRect(relBounds), toWrRect(overflow), transform, FrameMetrics::NULL_SCROLL_ID));
WRBridge()->AddWebRenderCommand(OpDPPushImage(toWrRect(rect), toWrRect(clip), Nothing(), key));
Manager()->AddImageKeyForDiscard(key);
if (gfxPrefs::LayersDump()) printf_stderr("PaintedLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
WRBridge()->AddWebRenderCommand(OpPopDLBuilder());
}
} // namespace layers

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

@ -44,7 +44,6 @@ extern {
pub struct WebRenderFrameBuilder {
pub root_pipeline_id: PipelineId,
pub root_dl_builder: webrender_traits::DisplayListBuilder,
pub dl_builder: Vec<webrender_traits::DisplayListBuilder>,
}
impl WebRenderFrameBuilder {
@ -52,7 +51,6 @@ impl WebRenderFrameBuilder {
WebRenderFrameBuilder {
root_pipeline_id: root_pipeline_id,
root_dl_builder: webrender_traits::DisplayListBuilder::new(root_pipeline_id),
dl_builder: vec![],
}
}
}
@ -246,8 +244,6 @@ pub extern fn wr_dp_begin(window: &mut WrWindowState, state: &mut WrState, width
assert!( unsafe { is_in_compositor_thread() });
state.size = (width, height);
state.frame_builder.root_dl_builder.list.clear();
state.frame_builder.dl_builder.clear();
state.frame_builder.dl_builder.push(webrender_traits::DisplayListBuilder::new(state.pipeline_id));
state.z_index = 0;
if state.pipeline_id == window.root_pipeline_id {
@ -269,26 +265,15 @@ pub extern fn wr_dp_begin(window: &mut WrWindowState, state: &mut WrState, width
}
#[no_mangle]
pub extern fn wr_push_dl_builder(state:&mut WrState)
pub extern fn wr_push_dl_builder(state:&mut WrState, bounds: WrRect, overflow: WrRect, transform: &LayoutTransform)
{
assert!( unsafe { is_in_compositor_thread() });
state.frame_builder.dl_builder.push(webrender_traits::DisplayListBuilder::new(state.pipeline_id));
}
#[no_mangle]
pub extern fn wr_pop_dl_builder(state: &mut WrState, bounds: WrRect, overflow: WrRect, transform: &LayoutTransform)
{
assert!( unsafe { is_in_compositor_thread() });
//
state.z_index += 1;
let bounds = bounds.to_rect();
let overflow = overflow.to_rect();
let mut dl = state.frame_builder.dl_builder.pop().unwrap();
let mut prev_dl = state.frame_builder.dl_builder.last_mut().unwrap();
prev_dl.push_stacking_context(webrender_traits::ScrollPolicy::Scrollable,
state.frame_builder.root_dl_builder.push_stacking_context(webrender_traits::ScrollPolicy::Scrollable,
bounds,
ClipRegion::simple(&overflow),
state.z_index,
@ -296,8 +281,15 @@ pub extern fn wr_pop_dl_builder(state: &mut WrState, bounds: WrRect, overflow: W
&LayoutTransform::identity(),
webrender_traits::MixBlendMode::Normal,
Vec::new());
prev_dl.list.append(&mut dl.list);
prev_dl.pop_stacking_context()
}
#[no_mangle]
pub extern fn wr_pop_dl_builder(state: &mut WrState)
{
assert!( unsafe { is_in_compositor_thread() });
//
state.frame_builder.root_dl_builder.pop_stacking_context()
}
fn wait_for_epoch(window: &mut WrWindowState) {
@ -360,11 +352,6 @@ pub extern fn wr_dp_end(window: &mut WrWindowState,
if let Some(epoch) = window.pipeline_epoch_map.get_mut(&pipeline_id) {
(*epoch).0 += 1;
// Should be the root one
assert!(state.frame_builder.dl_builder.len() == 1);
let mut dl = state.frame_builder.dl_builder.pop().unwrap();
state.frame_builder.root_dl_builder.list.append(&mut dl.list);
state.frame_builder.root_dl_builder.pop_stacking_context();
let fb = mem::replace(&mut state.frame_builder, WebRenderFrameBuilder::new(pipeline_id));
@ -415,10 +402,9 @@ pub extern fn wr_delete_image(window: &mut WrWindowState, key: ImageKey) {
#[no_mangle]
pub extern fn wr_dp_push_rect(state: &mut WrState, rect: WrRect, clip: WrRect, r: f32, g: f32, b: f32, a: f32) {
assert!( unsafe { is_in_compositor_thread() });
assert!(!state.frame_builder.dl_builder.is_empty());
let clip_region = state.frame_builder.dl_builder.last_mut().unwrap().new_clip_region(&clip.to_rect(), Vec::new(), None);
let clip_region = state.frame_builder.root_dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
state.frame_builder.dl_builder.last_mut().unwrap().push_rect(
state.frame_builder.root_dl_builder.push_rect(
rect.to_rect(),
clip_region,
ColorF::new(r, g, b, a));
@ -427,14 +413,13 @@ pub extern fn wr_dp_push_rect(state: &mut WrState, rect: WrRect, clip: WrRect, r
#[no_mangle]
pub extern fn wr_dp_push_iframe(window: &mut WrWindowState, state: &mut WrState, rect: WrRect, clip: WrRect, layers_id: u64) {
assert!( unsafe { is_in_compositor_thread() });
assert!(!state.frame_builder.dl_builder.is_empty());
let clip_region = state.frame_builder.dl_builder.last_mut().unwrap().new_clip_region(&clip.to_rect(),
let clip_region = state.frame_builder.root_dl_builder.new_clip_region(&clip.to_rect(),
Vec::new(),
None);
let pipeline_id = PipelineId((layers_id >> 32) as u32, layers_id as u32);
window.pipeline_sync_list.push(pipeline_id);
state.frame_builder.dl_builder.last_mut().unwrap().push_iframe(rect.to_rect(),
state.frame_builder.root_dl_builder.push_iframe(rect.to_rect(),
clip_region,
pipeline_id);
}
@ -467,7 +452,6 @@ impl WrRect
#[no_mangle]
pub extern fn wr_dp_push_image(state:&mut WrState, bounds: WrRect, clip : WrRect, mask: *const WrImageMask, key: ImageKey) {
assert!( unsafe { is_in_compositor_thread() });
assert!(!state.frame_builder.dl_builder.is_empty());
let bounds = bounds.to_rect();
let clip = clip.to_rect();
@ -475,8 +459,8 @@ pub extern fn wr_dp_push_image(state:&mut WrState, bounds: WrRect, clip : WrRect
// convert from the C type to the Rust type
let mask = unsafe { mask.as_ref().map(|&WrImageMask{image, ref rect,repeat}| ImageMask{image: image, rect: rect.to_rect(), repeat: repeat}) };
let clip_region = state.frame_builder.dl_builder.last_mut().unwrap().new_clip_region(&clip, Vec::new(), mask);
state.frame_builder.dl_builder.last_mut().unwrap().push_image(
let clip_region = state.frame_builder.root_dl_builder.new_clip_region(&clip, Vec::new(), mask);
state.frame_builder.root_dl_builder.push_image(
bounds,
clip_region,
bounds.size,

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

@ -139,13 +139,13 @@ wr_delete_image(wrwindowstate* wrWindow, WRImageKey key)
WR_FUNC;
WR_INLINE void
wr_push_dl_builder(wrstate *wrState)
wr_push_dl_builder(wrstate *wrState, WRRect bounds,
WRRect overflow, const float* matrix)
WR_FUNC;
//XXX: matrix should use a proper type
WR_INLINE void
wr_pop_dl_builder(wrstate *wrState, WRRect bounds,
WRRect overflow, const float* matrix)
wr_pop_dl_builder(wrstate *wrState)
WR_FUNC;
WR_INLINE void