mozilla
Your Search Results

    Introduction to Layout in Mozilla

    Overview

    • Basic data flow
    • Key data structures
    • Detailed walk-through
    • Incrementalism
    • Future tech-talks
    • Wrap-up, Q&A

    Basic Data Flow

    • Source document arrives via network APIs
    • Incrementally “pumped” through the single-threaded layout engine
      • Parse, compute style, render; repeat
      • CSS used for rendering all content
    • Content theoretically separate from “presentation”

    Key Data Structures

    • Content node
      • Elements, attributes, leaves
      • DOM
    • Frame
      • Rectangular formatting primitive
      • Geometric information
      • [0..n] per content node
      • 2nd thru nth are “continuations”
    • Style context
      • Non-geometric information
      • May be shared by adjacent frames
      • Reference counted, owned by frame
    • View
      • Clipping, z-order, transparency
      • [0..1] per frame, owned by frame
    • Widget
      • Native window
      • [0..1] per view, owned by view

    Key Data Structures

    • The document owns the content model, and one or more presentations
      • Exposed programmatically via DOM APIs
    • The presentation owns the frame hierarchy
      • Frames own the style contexts, views, widgets
      • Presentation has media type, dimensions, etc.
      • May not be directly manipulated

    Detailed Walk-Through

    • Setting up
    • Content model construction
    • Frame construction
    • Style resolution
    • Reflow
    • Painting

    Setting Up

    • Assume basic knowledge of embedding and network APIs (doc shell, streams)
    • Content DLL auto-registers a Document Loader Factory (DLF)
      • @mozilla.org/content-viewer-factory/view;1?type=text/html
      • All MIME types mapped to the same class, nsContentDLF
    • nsDocShell
      • Receives inbound content via nsDSURIContentListener
      • Invokes nsIDLF::CreateInstance, passes MIME type to DLF
    • nsContentDLF
      • Creates a nsHTMLDocument object, invokes StartDocumentLoad.
        • Creates a parser, returned as nsIStreamListener back to the docshell
        • Creates a content sink, which is linked to the parser and the document
      • Creates a DocumentViewerImpl object, which is returned as nsIContentViewer back to the docshell
    • DocumentViewerImpl creates pres context and pres shell

    Content Model Construction

    • Content arrives from network via nsIStreamListener::OnDataAvailable
    • Parser tokenizes & processes content; invokes methods on nsIContentSink with parser node objects
      • Some buffering and fixup occurs here
      • OpenContainer, CloseContainer, AddLeaf
    • Content sink creates and attaches content nodes using nsIContent interface
      • Content sink maintains stack of “live” elements
      • More buffering and fixup occurs here
      • InsertChildAt, AppendChildTo, RemoveChildAt

    Frame Construction

    • Content sink uses nsIDocument interface to notify of Δs in content model
      • ContentAppended, ContentInserted, ContentRemoved
    • PresShell is registered as document observer
      • Receives ContentAppended, etc. notifications
      • Passes these to the style set object, who in turn passes to the frame constructor
    • Frame constructor creates frames
      • ConstructFrameInternal recursively walks content tree, resolves style and creates frames
      • Either created by tag (<select>) or by display type (<p>)
    • Frame manager maintains mapping from content to frame

    Style Resolution

    • Compute stylistic information based on the style rules that apply for the frame’s content node
    • Style data broken into different structures
      • Display, visibility, font, color, background, …
      • Inherit vs. reset
    • Style context object is a placeholder for partially computed stylistic data
      • Style data is computed lazily, as it is asked for

    Reflow

    • Recursively compute geometry (x, y, w, h) for frames, views, and widgets
      • Given w & h constraints of “root frame” compute (x, y, w, h) for all children
      • Constraints propagated “down” via nsHTMLReflowState
      • Desired size returned “up” via nsHTMLReflowMetrics
    • Basic pattern
      • Parent frame initializes child reflow state (available w, h); places child frame (x, y); invokes child’s Reflow method
      • Child frame computes desired (w, h), returns via reflow metrics
      • Parent frame sizes child frame and view based on child’s metrics
    • N.B. many don’t work like this! (Tables, blocks, XUL boxes)

    Reflow

    • “Global” reflows
      • Initial, resize, style-change
      • Processed immediately via PresShell method
    • Incremental reflows
      • Targeted at a specific frame
      • Dirty, content-changed, style-changed, user-defined
      • nsHTMLReflowCommand object encapsulates info
      • Queued and processed asynchronously, nsIPressShell::AppendReflowCommand, ProcessReflowCommands

    Incremental Reflow

    • Recursively descend to target recovering reflow state
      • Child rs.reason set to incremental

    Incremental Reflow

    • Process reflow “normally” at target frame
      • Child rs.reason set based on rc’s type

    Incremental Reflow

    • Propagate damage to frames later “in the flow”

    Incremental Reflow

    • Multiple reflow commands are batched
      • nsReflowPath maintains a tree of target frames
      • Amortize state recovery and damage propagation cost

    Painting

    • As reflow proceeds through the frame hierarchy, areas are invalidated via nsIViewManager::UpdateView
    • Unless immediate, invalid areas are coalesced and processed asynchronously via OS expose event
    • Native expose event dispatched to widget; widget delegates to the view manager
    • View manager paints views back-to-front, invoking PresShell’s Paint method
    • PresShell::Paint walks from the view to the frame; invokes nsIFrame::Paint for each layer

    Incrementalism

    • Single-threaded
      • Simple (no locking)
      • Can’t leave event queue unattended
    • Content construction unwinds “at will”
      • Parser and content sink do some buffering
      • Content sink has “notification limits”
      • Efficiency vs. responsiveness trade-off
    • Frame construction runs to completion
    • CSS parsing runs to completion
    • Reflow runs to completion (mostly)
    • Painting runs to completion

    Future (?) Tech Talks

    • Content model and DOM - jst, jkeiser
    • Parser and content sink (esp. invalid content) - harishd
    • Events - saari, joki
    • Block-and-line reflow - waterson, dbaron
    • Table reflow - karnaze
    • Form controls - rods, bryner
    • Style resolution and rule tree - dbaron
    • Views, widgets, and painting - roc, kmcclusk
    • Editor - kin, jfrancis
    • XUL and box layout - hewitt, ben
    • XBL - hewitt, ben

    Conclusion

    • Data flow
    • Key data structures
    • Detailed walk-through
    • Incrementalism
    • Q & A?

    Original Document Information

    • Author(s): Chris Waterson
    • Last Updated Date: June 10, 2002
    • Copyright Information: Portions of this content are © 1998–2007 by individual mozilla.org contributors; content available under a Creative Commons license | Details.

    Document Tags and Contributors

    Tags: 
    Contributors to this page: Kohei, DBaron, ethertank, Kennykaiyinyu
    Last updated by: ethertank,