forked from mirrors/gecko-dev
		
	 43c68653a5
			
		
	
	
		43c68653a5
		
	
	
	
	
		
			
			GECKO_DISPLAY_REFLOW_RULES_FILE doesn't work when the sandbox prevents access to the rules file. Added mention to try `--setpref security.sandbox.content.level=2` to lower sandbox defenses. As a workaround, and because in most cases the rules are only "* 1" (log everything), a new env-var GECKO_DISPLAY_REFLOW_PROCESSES=a/p/c enables all reflow logging without needing a rules file. It also adds the choice of which processes have logging enabled, based on the giving letter: - a: All processes, - p: Parent process, - c: Content processes. MozReview-Commit-ID: 9ymjtuXoF9r --HG-- extra : rebase_source : fc164bf7c1982ff163b5f6276f341b497dfed961
		
			
				
	
	
		
			237 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			237 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!-- This Source Code Form is subject to the terms of the Mozilla Public
 | |
|    - License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 | |
| 
 | |
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
 | |
| <html>
 | |
|  <head>
 | |
|  <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
 | |
|   <style type="text/css">
 | |
|   body {font-family:arial}
 | |
| .log {background-color:silver; color:blue}
 | |
|   </style>
 | |
|   <title> Debugging Frame Reflow</title>
 | |
|  </head>
 | |
|  <body>
 | |
| <h1>Debugging Frame Reflow HowTo</h1>
 | |
| <h2>General Overview</h2>
 | |
| <p> The frame reflow can be logged with the debug capabilities implemented in <a href="http://lxr.mozilla.org/seamonkey/source/layout/html/base/src/nsFrame.cpp"><code>nsFrame.cpp</code></a>. 
 | |
| It provides the following information for each frame at the
 | |
| start of its reflow
 | |
| <ul>
 | |
| <li>reflow reason
 | |
| <li>available width, available height
 | |
| <li>computed width, computed height
 | |
| <li>the previous and the next frame in flow
 | |
| <li>and a count number.
 | |
| </ul>
 | |
| <p>When the frame's reflow is finished the following information is displayed :</p>
 | |
| <ul>
 | |
| <li>reflow metric (desired)  width, height
 | |
| <li>max. element size (MES) width
 | |
| <li>maximum Width
 | |
| <li>frame status
 | |
| <li>overflow area
 | |
| </ul>
 | |
| 
 | |
| <h2>Getting the log</h2>
 | |
| <ul>
 | |
| <li>Make sure that your build is a <b>debug</b> build.
 | |
| <li>Either:
 | |
| <ol>
 | |
| <li>Select which processes should log all reflow debugging:
 | |
| <ul>
 | |
| <li><code>set GECKO_DISPLAY_REFLOW_PROCESSES=a</code> to log from all processes
 | |
| <li><code>set GECKO_DISPLAY_REFLOW_PROCESSES=p</code> to log from the parent process
 | |
| <li><code>set GECKO_DISPLAY_REFLOW_PROCESSES=c</code> to log from e10s content processes
 | |
| </ul>
 | |
| <li>OR create a rules file:
 | |
| <ul>
 | |
| <li>Create a text file (for instance <code>reflow_rules.txt</code>).
 | |
| <li>Enter this line  in the text file <pre>* 1</pre>
 | |
| <li>Save the text file in the <code>%DIST%</code> directory
 | |
| <li>Go to the <code>%DIST%</code> directory
 | |
| <li>enter from command line: <code>set GECKO_DISPLAY_REFLOW_RULES_FILE=reflow_rules.txt</code>
 | |
| <li>Note: If Firefox fails to read the file, it may be because of sandboxing, try `--setpref security.sandbox.content.level=2` as workaround.
 | |
| </ul>
 | |
| </ol>
 | |
| <li> Run <code>viewer > logfile.txt</code> and load your testcase. The
 | |
| logfile will contain all the promised information.
 | |
| </ul>
 | |
| <h2>Log File analyis</h2>
 | |
| <p>The logfile for a simple table like</p>
 | |
| <pre>
 | |
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | |
| <html>
 | |
| <head>
 | |
|   <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
 | |
| </head>
 | |
| <body>
 | |
| <table width="100">
 | |
|   <tbody>
 | |
|     <tr>
 | |
|       <td>foo</td>
 | |
|     </tr>
 | |
|   </tbody>
 | |
| </table>
 | |
| </body>
 | |
| </html>
 | |
| </pre>
 | |
| 
 | |
| <p> will create the following log:</p>
 | |
| <table class="log"><tr><td>
 | |
| <pre>
 | |
| VP 00B97C30 r=0 a=9180,4470 c=9180,4470 cnt=856 
 | |
|  scroll 00B97EE0 r=0 a=9180,4470 c=9180,4470 cnt=857 
 | |
|  scroll 00B97EE0 r=0 a=9180,4470 c=9180,4470 cnt=858 
 | |
|   canvas 00B97C6C r=0 a=9180,UC c=9180,4470 cnt=859 
 | |
|    area 02D7AFE4 r=0 a=9180,UC c=9180,UC cnt=860 
 | |
|     text 02D7B150 r=0 a=9180,UC c=UC,UC cnt=861 
 | |
|     text 02D7B150 d=0,0 
 | |
|     block 02D7B210 r=0 a=9180,UC c=8940,UC cnt=862 
 | |
|     block 02D7B210 d=8940,0 
 | |
|    area 02D7AFE4 d=9180,120 
 | |
|   canvas 00B97C6C d=9180,4470 
 | |
|  scroll 00B97EE0 d=9180,4470 
 | |
|  scroll 00B97EE0 d=9180,4470 
 | |
| VP 00B97C30 d=9180,4470 
 | |
| VP 00B97C30 r=1 a=9180,4470 c=9180,4470 cnt=863 
 | |
|  scroll 00B97EE0 r=1 a=9180,4470 c=9180,4470 cnt=864 
 | |
|  scroll 00B97EE0 r=1 a=9180,4470 c=9180,4470 cnt=865 
 | |
|   canvas 00B97C6C r=1 a=9180,UC c=9180,4470 cnt=866 
 | |
|    area 02D7AFE4 r=1 a=9180,UC c=9180,UC cnt=867 
 | |
|     block 02D7B210 r=1 a=9180,UC c=8940,UC cnt=868 
 | |
|      text 02D7B3F8 r=0 a=8940,UC c=UC,UC cnt=869 
 | |
|      text 02D7B3F8 d=0,0 
 | |
|      tblW 02D7B5F0 r=0 a=8940,UC c=0,0 cnt=870 
 | |
|       tbl 02D7B7EC r=0 a=8940,UC c=1500,UC cnt=871 
 | |
|        rowG 00B984A4 r=0 a=UC,UC c=UC,UC cnt=872 
 | |
|         row 02D7BAF8 r=0 a=UC,UC c=UC,UC cnt=873 
 | |
|          cell 02D7BC98 r=0 a=UC,UC c=UC,UC cnt=874 
 | |
|           block 02D7BCF8 r=0 a=UC,UC c=UC,UC cnt=875 
 | |
|            text 02D7BE84 r=0 a=UC,UC c=UC,UC cnt=876 
 | |
|            text 02D7BE84 d=300,285 me=300 
 | |
|           block 02D7BCF8 d=300,300 me=300 
 | |
|          cell 02D7BC98 d=330,330 me=330 
 | |
|         row 02D7BAF8 d=UC,330 
 | |
|        rowG 00B984A4 d=UC,330 
 | |
|        colG 02D7BFB0 r=0 a=UC,UC c=UC,UC cnt=877 
 | |
|         col 02D7C0D8 r=0 a=0,0 c=1500,UC cnt=878 
 | |
|         col 02D7C0D8 d=0,0 
 | |
|        colG 02D7BFB0 d=0,0 
 | |
|        rowG 00B984A4 r=2 a=1500,UC c=1500,UC cnt=879 
 | |
|         row 02D7BAF8 r=2 a=1500,UC c=1500,UC cnt=880 
 | |
|          cell 02D7BC98 r=2 a=1440,UC c=1410,UC cnt=881 
 | |
|           block 02D7BCF8 r=2 a=1410,UC c=1410,UC cnt=882 
 | |
|           block 02D7BCF8 d=1410,300 
 | |
|          cell 02D7BC98 d=1440,330 
 | |
|         row 02D7BAF8 d=1500,330 
 | |
|        rowG 00B984A4 d=1500,330 
 | |
|        colG 02D7BFB0 r=2 a=1500,UC c=1500,UC cnt=883 
 | |
|         col 02D7C0D8 r=0 a=0,0 c=1500,UC cnt=884 
 | |
|         col 02D7C0D8 d=0,0 
 | |
|        colG 02D7BFB0 d=0,0 
 | |
|       tbl 02D7B7EC d=1500,390 
 | |
|      tblW 02D7B5F0 d=1500,390 
 | |
|      text 02D7C130 r=0 a=8940,UC c=UC,UC cnt=885 
 | |
|      text 02D7C130 d=0,0 
 | |
|     block 02D7B210 d=8940,390 
 | |
|    area 02D7AFE4 d=9180,630 
 | |
|   canvas 00B97C6C d=9180,4470 
 | |
|  scroll 00B97EE0 d=9180,4470 
 | |
|  scroll 00B97EE0 d=9180,4470 
 | |
| VP 00B97C30 d=9180,4470 
 | |
| </pre>
 | |
| </td></tr></table>
 | |
| <p>
 | |
| The first line shows the reflow of the viewport (<code class="log">VP</code>). This viewport has the address <code class="log">00B97C30</code>. It is the initial reflow: <code class="log">r=0</code>. Other reflow reasons are: </p>
 | |
| <table>
 | |
| <tr><td>1</td><td>incremental reflow</td></tr>
 | |
| <tr><td>2</td><td>resize reflow</td></tr>
 | |
| <tr><td>3</td><td>style change reflow</td></tr>
 | |
| <tr><td>4</td><td>dirty reflow.</td></tr>
 | |
| </table>
 | |
| 
 | |
| <p>The available width is 9180 twips. The available height is 4470 twips (<code class="log">a=9180,4470</code>). The computed width is 9180 twips. The computed height is 4470 twips (<code class="log">c=9180,4470</code>). The line count is 856 (<code  class="log">cnt=856</code>).
 | |
| <p>
 | |
| Below this is a line that reads:<p><code class="log">tblW 02D7B5F0 r=0 a=8940,UC c=0,0 cnt=870</code></p><p> Here the <code class="log">UC</code> shows that on initial reflow the available height for the table wrapper frame is unconstrained.
 | |
| <p>
 | |
| The table cell requires its children to compute the MES. It is reported back from the block as:
 | |
| <p><code class="log">block 02D7BCF8 d=300,300 me=300</code></p>
 | |
| <p>The  block max. element size is 300 twips.
 | |
| <p> The second table reflow is started at 
 | |
| <p><code class="log">rowG 00B984A4 r=2 a=1500,UC c=1500,UC cnt=879</code></p>
 | |
| <p>where the previous information is used. 
 | |
| The block has been required to compute the max. element size only once and it reports now:
 | |
| <p> <code class="log">block 02D7BCF8 d=1410,300</code></p>
 | |
| <p>The block shows the same address as the previous one. 
 | |
| <p>Frames with children that overflow  the parent will return <code>PR_TRUE</code> from <code>HasOverflowRect()</code>. For these frames 
 | |
| the overflow area  is displayed as  <code class="log">block 025ED8F0 d=8940,1020 o=(0,0) 9180 x 1020</code>. The overflow area is specified as (x,y) origin and width x height.
 | |
| <p> The reflow finishes at the same level where it started.
 | |
| 
 | |
| <h2>Advanced reflow debugging</h2>
 | |
| <p>The previously described technique dumps the data for every frame. Sometimes the log is clearer if only the main frames are shown.
 | |
| The entries in the reflow log can be controlled on a frame level.  For instance adding <code>text 0</code> to the rules in <code>reflow_rules.txt</code> would hide the text entries from the reflow. The display of the following frames can be turned on by adding a line with the frame name and  <code>1</code>  or turned off by adding a line with the frame name and <code>0</code>:</p>
 | |
| <table cellspacing="5">
 | |
|  <tr><th style="text-align:left">short name</th><th style="text-align:left">layout tag</th></tr>
 | |
|  <tr><td>area</td><td>area</td></tr>
 | |
|  <tr><td>block</td><td>block</td></tr>
 | |
|  <tr><td>br</td><td>br</td></tr>
 | |
|  <tr><td>bullet</td><td>bullet</td></tr>
 | |
|  <tr><td>button</td><td>gfxButtonControl</td></tr>
 | |
|  <tr><td>hr</td><td>hr</td></tr>
 | |
|  <tr><td>frameI</td><td>htmlFrameInner</td></tr>
 | |
|  <tr><td>frameO</td><td>htmlFrameOuter</td></tr>
 | |
|  <tr><td>img</td><td>image</td></tr>
 | |
|  <tr><td>inline</td><td>inline</td></tr>
 | |
|  <tr><td>letter</td><td>letter</td></tr>
 | |
|  <tr><td>line</td><td>line</td></tr>
 | |
|  <tr><td>select</td><td>select</td></tr>
 | |
|  <tr><td>obj</td><td>object</td></tr>
 | |
|  <tr><td>page</td><td>page</td></tr>
 | |
|  <tr><td>place</td><td>placeholder</td></tr>
 | |
|  <tr><td>canvas</td><td>canvas</td></tr>
 | |
|  <tr><td>root</td><td>root</td></tr>
 | |
|  <tr><td>scroll</td><td>scroll</td></tr>
 | |
|  <tr><td>caption</td><td>tableCaption</td></tr>
 | |
|  <tr><td>cell</td><td>tableCell</td></tr>
 | |
|  <tr><td>bcCell</td><td>bcTableCell</td></tr>
 | |
|  <tr><td>col</td><td>tableCol</td></tr>
 | |
|  <tr><td>colG</td><td>tableColGroup</td></tr>
 | |
|  <tr><td> tbl</td><td>table</td></tr>
 | |
|  <tr><td>tblW</td><td>tableWrapper</td></tr>
 | |
|  <tr><td>rowG</td><td>tableRowGroup</td></tr>
 | |
|  <tr><td>row</td><td>tableRow</td></tr>
 | |
|  <tr><td>textCtl</td><td>textInput</td></tr>
 | |
|  <tr><td>text</td><td>text</td></tr>
 | |
|  <tr><td>VP</td><td>viewport</td></tr>
 | |
| </table>
 | |
| <p>Once the problem is reduced to a single frame level, placing a breakpoint at <code>DisplayReflowEnterPrint</code> in <a href="http://lxr.mozilla.org/seamonkey/source/layout/html/base/src/nsFrame.cpp"><code>nsFrame.cpp</code></a> is a very efficient way to step through
 | |
|  the reflow tree.
 | |
| 
 | |
| <h2>Other reflow debug options</h2>
 | |
| 
 | |
| <h3>GECKO_DISPLAY_REFLOW_FLAG_PIXEL_ERRORS</h3>
 | |
| <p>
 | |
| Setting this option via <code>set GECKO_DISPLAY_REFLOW_FLAG_PIXEL_ERRORS = 1</code> enables a verification for each coordinate value that the coordinates are aligned at pixel boundaries.
 | |
| <table class="log"><tr><td>
 | |
| <pre>
 | |
|               row 0268A594 r=0 a=UC,UC c=UC,20 cnt=870 
 | |
| VALUE 20 is not a whole pixel 
 | |
|                cell 0268A6C0 r=0 a=UC,UC c=UC,15 cnt=871 
 | |
|                 block 0268A764 r=0 a=UC,UC c=UC,UC cnt=872 
 | |
|                 block 0268A764 d=0,0 me=0 
 | |
|                cell 0268A6C0 d=0,0 me=0 
 | |
|               row 0268A594 d=UC,20 
 | |
| VALUE 20 is not a whole pixel 
 | |
|              rowG 0268A02C d=UC,695 
 | |
| VALUE 695 is not a whole pixel</pre>
 | |
| </td></tr></table>
 | |
| <p>
 | |
| While unaligned values at the entrance of a frame reflow can be ignored,  when they appear at the exit of a routine this can cause display errors like stray lines. OS2 is very vulnerable to pixel alignement errors as text is drawn on pixel boundaries.
 | |
| 
 | |
| <h3>GECKO_DISPLAY_REFLOW_INDENT_UNDISPLAYED_FRAMES</h3>
 | |
| <p>
 | |
| Setting this option via <code>set GECKO_DISPLAY_REFLOW_INDENT_UNDISPLAYED_FRAMES = 1</code> will cause an advance of the indent even for frames which are blocked via the reflow rules file.  
 | |
|  </body>
 | |
| </html>
 |