Hi everyone,

I had an idea for how to handle block formatting contexts impacted by floats in a way that doesn't sacrifice parallelism, with some speculation. I'd like to get feedback on people's intuitions as to (a) whether this is likely to pay off; (b) whether this works :)

Recall that block formatting contexts are a special kind of block whose *actual width* (not the width of individual *lines* as is normally done) depends on floats next to it. The most common way to create a block formatting context is to use the property `overflow: hidden`. This is commonly used to create sidebar layouts, which I first noticed on this page [1]. It causes a problem for Servo because Servo wants to assign widths before assigning heights, but block formatting contexts make width assignment possibly depend on height assignment. Consider this page:

    <div style="float: right">float1</div>
    <div>blah blah blah</div>
    <div style="float: right">float2</div>
    <div style="overflow: hidden; border: solid black 1px"></div>

Depending on the heights of the floats, we have no idea if this renders as:

    blah blah        float1
    blah
                     float2
    +--------------+
    |              |
    +--------------+

Or:

    blah blah        float1
    blah      float2
    +-------+
    |       |
    +-------+

We only know the positions of the heights after performing height assignment, so this causes a problem.

What I did in my previous pull request [2] is to have the notion of "suspended height computation" and "deferred width computation". This intertwines the two passes in a tricky way: we compute beforehand whether a block formatting context was potentially impacted by floats, and delay its width computation until the heights of floats next to it and the heights of preceding blocks are known. This requires that the parent of the block formatting context be able to *suspend* and *resume* its height computation once the width of the block formatting context has been computed, which adds quite a bit of complexity because now we have to save and restore state and so forth.

I realized, however, that with some speculation we may be able to eliminate this complexity, as well as gain the more parallelism back if the speculation pays off. What we do is to *speculate that a block formatting context will be impacted by the minimum number of floats that it possibly could be, assuming the floats' height is nonzero*. In other words, we speculate that the width of a block formatting context that was impacted by floats is the width of its container minus the width of the float that immediately precedes it, if any (correctly accounting for borders/padding/margins of course). Layout proceeds as normal; in particular, we need not perform sequential traversals for the block formatting context and can lay it out in parallel.

When we go to compute assign-heights for the parent block of the block formatting context, we verify that our width guess was correct. If it was incorrect, we record the correct width and perform assign-widths and assign-heights again for the subtree rooted at the parent of the block formatting context.

This will correctly predict the layout on that subreddit, and I imagine it correctly predicts the layout on most pages that are using block formatting contexts for sidebars. It also allows for a large degree of parallelism even in the presence of floats; all blocks on that page can be laid out in parallel assuming the speculation guessed correctly. (In fact, I can imagine that even if the speculation failed, we might still barely win due to the parallelism, though this is of course risky.) The code simplification that this affords—allowing width assignment and height assignment to stay separate and avoiding complicated logic to suspend and resume height assignment—is attractive as well from a maintainability point of view (and possibly performance as well in cases that don't involve block formatting contexts).

Any thoughts?

Patrick

[1]: http://www.reddit.com/r/Bitcoin/comments/23flcn/bits_instead_of_%CE%BCbtc/

[2]: https://github.com/mozilla/servo/pull/1734
_______________________________________________
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo

Reply via email to