Gecko:Frame Painting

Revision as of 12:12, 16 March 2005 by Ognyan Kulev (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Currently our handling of stacking contexts and z-ordering is deficient because nsIFrame::Paint can't separate the painting of a frame's background from the painting of its children. See bug #78087. To fix this we need to refactor painting and possibly event handling.

We also have some problems because currently a frame with a view paints all its descendant frames-without-views in one go. Sometimes that's not correct. e.g.:

     F (V) 
      / \\  

  F1(V1)  F2 

we'll build a display list "V V1"; painting V paints F and F2. So the rendered order is F F2 F1, which is wrong.

The main problem is to integrate the stacking context description http://www.w3.org/TR/CSS21/zindex.html with view display lists. We still need view display lists to avoid painting hidden frames/views and to orchestrate opacity efficiently (and also to figure out when bitblit scrolling is allowed).

The stacking context description implies that there are four phases of frame painting that need to be separable, given that we have views for all frames with stacking contexts and for all positioned frames.

  • The background and borders of a block-level or root element (steps 1 and 2)
  • The background and borders of the frame's in-flow non-positioned block-level descendants (step 4)
  • Floating descendants (step 5)
  • The frame's inline-level and replaced descendants (step 6)

We also need to be able to ask for these things separately on frame so we can implement the appropriate recursive descents for the latter three cases.

Here's a plan: create view observer paint flags for those four cases, as my current patch in bug #78087 does for just the background and foreground cases:

  • NS_VIEW_PAINT_BLOCK_BACKGROUND
  • NS_VIEW_PAINT_DESCENDANT_BLOCK_BACKGROUND
  • NS_VIEW_PAINT_FLOATS
  • NS_VIEW_PAINT_FOREGROUND

The view manager will be responsible for sorting the display list so that for frames with views, we do the steps 1-7 in the right order. Within each step, and for frames without views, the frame system will be responsible for doing things in the right order. Note that frames that establish stacking contexts (or are treated as such) and that contain positioned children will always have views so the frame system never needs to deal with steps 3, 7 and 8. (This isn't quite true since floats currently don't always have views; we'll fix that.)

To make the above example work, we'll have to change the way painting is organized between the view manager and the pres-shell. Here's how I think it will work: When we ask a frame to paint a layer, it does a recursive traversal of its children. When one of those children has a view, we currently just ignore it. Instead, let's call back to the view manager saying "we found a view, please render it". The view manager will peek at the display list and see if this view should indeed be rendered at this point in the z-order. If so, then the view manager will go ahead and render it and all its children, and advance the display list pointer so it doesn't get rendered again. Otherwise the view manager will just return without rendering anything. This allows a frame with a view to be rendered interspersed with its frame siblings.