> By contrast, approach #1 (Gecko's approach) avoids the unbounded amount of
> information flow in the opposite direction to the traversal. The height and
> overflow region only need to travel one step: from containing block to its
> immediate absolutely positioned flow child and back. This can be implemented
> by simply moving the computation of height and overflow of
> absolutely-positioned frames to the parent. This loses a small amount of
> parallelism during the assign-heights phase, but it should be small with
> fixed overhead.

I think we talked about this a bit at the work week and had also
settled on this idea.

> This can be remedied by simply (a) having containing blocks
> *not* enqueue their absolutely-positioned kids in the usual manner during
> the parallel top-down traversal and (b) having the *hypothetical* frame be
> the frame responsible for computing its associated absolutely positioned
> frame's width, and enqueuing its kids.
>
> Unfortunately, I don't know off the top of my head the best way to enforce
> that this logic is correct in the Rust type system.

Tthe other issue is that there's no reason we can't mix the
traversals. Once we've done assign_widths on a leaf node, for example,
we should be able to enqueue assign_heights on the leaf node
immediately. But we'll need to enforce that we don't enqueue the
abspos child of a containing block until it's hypothetical flow is
finished, not to mention that we may attempt to enqueue it *before*
the hypothetical child has even gotten to assign widths, much less
assign heights.

I'm not sure how to enforce this in the type system, but we can
certainly express the invariants in the enqueuing function somehow.

> There is one minor issue of reference counting flows: there will need to be
> a reference from the absolutely-positioned flow to its hypothetical flow (so
> that the flow can find its static position if need be) and vice versa (so
> that width can be assigned as above). At least one of these references must
> be a strong reference. This is not too big of an issue because we need to
> reference count flows for incremental reflow at some point anyway.

I assume having the strong reference be the one from hypothetical up
to the abspos flow child of the containing block is easiest since flow
tree construction is bottom up. Incremental flow tree construction
will have to be pretty careful not to leave a pointer dangling. We
might blow away a subtree that contains the hypothetical flow but not
the abspos kid. Perhaps the containing block has only weak pointers to
its abspos kids, and they are really owned by the their hypothetical
flow.

I assume we can measure the overhead pretty easily on real pages
similar to how we're discussing measuring float impact on parallelism.
My rough guess is that the overhead will be proportional to the depth
differential between the containing block and the hypothetical flow.
Or perhaps proportional to the size of the subtree to the depth of the
hypothetical flow.

> I'm assuming you swapped #1 and #2 here.
> positions. This will almost certainly break the Web, so I'm not suggesting
> that we do this for the long run, but I think landing complicated work like
> this is best done piecemeal.

+1 as long as we do this work in the short term.

jack.
_______________________________________________
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo

Reply via email to