Bug 786387 - Add comments to document the subtleties of nsFrame::Reflow and better document the main dirty frame bits. r=bz.
authorJonathan Watt <jwatt@jwatt.org>
Wed, 29 Aug 2012 09:01:09 +0100
changeset 105785 5a03f87a931b88430dc60e12fb74d10304c51833
parent 105781 418d50c7c3a574def2667ce9a00bd5a8ee6bb7cc
child 105786 91d39d72ac86b08a20e8039fd90841be17a2adf5
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersbz
bugs786387
milestone18.0a1
Bug 786387 - Add comments to document the subtleties of nsFrame::Reflow and better document the main dirty frame bits. r=bz.
layout/generic/nsFrame.h
layout/generic/nsIFrame.h
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -291,16 +291,38 @@ public:
   /**
    * Utility function for ComputeAutoSize implementations.  Return
    * max(GetMinWidth(), min(aWidthInCB, GetPrefWidth()))
    */
   nscoord ShrinkWidthToFit(nsRenderingContext *aRenderingContext,
                            nscoord aWidthInCB);
 
   NS_IMETHOD  WillReflow(nsPresContext* aPresContext);
+  /**
+   * Calculates the size of this frame after reflowing (calling Reflow on, and
+   * updating the size and position of) its children, as necessary.  The
+   * calculated size is returned to the caller via the nsHTMLReflowMetrics
+   * outparam.  (The caller is responsible for setting the actual size and
+   * position of this frame.)
+   *
+   * A frame's children must _all_ be reflowed if the frame is dirty (the
+   * NS_FRAME_IS_DIRTY bit is set on it).  Otherwise, individual children
+   * must be reflowed if they are dirty or have the NS_FRAME_HAS_DIRTY_CHILDREN
+   * bit set on them.  Otherwise, whether children need to be reflowed depends
+   * on the frame's type (it's up to individual Reflow methods), and on what
+   * has changed.  For example, a change in the width of the frame may require
+   * all of its children to be reflowed (even those without dirty bits set on
+   * them), whereas a change in its height might not.
+   * (nsHTMLReflowState::ShouldReflowAllKids may be helpful in deciding whether
+   * to reflow all the children, but for some frame types it might result in
+   * over-reflow.)
+   *
+   * Note: if it's only the overflow rect(s) of a frame that need to be
+   * updated, then UpdateOverflow should be called instead of Reflow.
+   */
   NS_IMETHOD  Reflow(nsPresContext*          aPresContext,
                      nsHTMLReflowMetrics&     aDesiredSize,
                      const nsHTMLReflowState& aReflowState,
                      nsReflowStatus&          aStatus);
   NS_IMETHOD  DidReflow(nsPresContext*           aPresContext,
                         const nsHTMLReflowState*  aReflowState,
                         nsDidReflowStatus         aStatus);
   void ReflowAbsoluteFrames(nsPresContext*           aPresContext,
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -165,35 +165,43 @@ typedef uint64_t nsFrameState;
 
 // If this bit is set, then the frame has been moved out of the flow,
 // e.g., it is absolutely positioned or floated
 #define NS_FRAME_OUT_OF_FLOW                        NS_FRAME_STATE_BIT(8)
 
 // This bit is available for re-use.
 //#define NS_FRAME_SELECTED_CONTENT                   NS_FRAME_STATE_BIT(9)
 
-// If this bit is set, then the frame is dirty and needs to be reflowed.
+// If this bit is set, then the frame and _all_ of its descendant frames need
+// to be reflowed.
 // This bit is set when the frame is first created.
 // This bit is cleared by DidReflow after the required call to Reflow has
 // finished.
 // Do not set this bit yourself if you plan to pass the frame to
 // nsIPresShell::FrameNeedsReflow.  Pass the right arguments instead.
 #define NS_FRAME_IS_DIRTY                           NS_FRAME_STATE_BIT(10)
 
 // If this bit is set then the frame is too deep in the frame tree, and
 // we'll stop updating it and its children, to prevent stack overflow
 // and the like.
 #define NS_FRAME_TOO_DEEP_IN_FRAME_TREE             NS_FRAME_STATE_BIT(11)
 
-// If this bit is set, either:
-//  1. the frame has children that have either NS_FRAME_IS_DIRTY or
-//     NS_FRAME_HAS_DIRTY_CHILDREN, or
-//  2. the frame has had descendants removed.
-// It means that Reflow needs to be called, but that Reflow will not
-// do as much work as it would if NS_FRAME_IS_DIRTY were set.
+// If this bit is set, then either:
+//  1. the frame has at least one child that has the NS_FRAME_IS_DIRTY bit or
+//     NS_FRAME_HAS_DIRTY_CHILDREN bit set, or
+//  2. the frame has had at least one child removed since the last reflow, or
+//  3. the frame has had a style change that requires the frame to be reflowed
+//     but does not _necessarily_ require its descendants to be reflowed (e.g.,
+//     for a 'height', 'width', 'margin', etc. change, it's up to the
+//     applicable Reflow methods to decide whether the frame's children
+//     _actually_ need to be reflowed).
+// If this bit is set but the NS_FRAME_IS_DIRTY is not set, then Reflow still
+// needs to be called on the frame, but Reflow will likely not do as much work
+// as it would if NS_FRAME_IS_DIRTY were set. See the comment documenting
+// nsFrame::Reflow for more.
 // This bit is cleared by DidReflow after the required call to Reflow has
 // finished.
 // Do not set this bit yourself if you plan to pass the frame to
 // nsIPresShell::FrameNeedsReflow.  Pass the right arguments instead.
 #define NS_FRAME_HAS_DIRTY_CHILDREN                 NS_FRAME_STATE_BIT(12)
 
 // If this bit is set, the frame has an associated view
 #define NS_FRAME_HAS_VIEW                           NS_FRAME_STATE_BIT(13)