Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | <!-- This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | - License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> |
michael@0 | 4 | |
michael@0 | 5 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> |
michael@0 | 6 | <html> |
michael@0 | 7 | <head> |
michael@0 | 8 | <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> |
michael@0 | 9 | <style type="text/css"> |
michael@0 | 10 | body {font-family:arial} |
michael@0 | 11 | .log {background-color:silver; color:blue} |
michael@0 | 12 | </style> |
michael@0 | 13 | <title> Debugging Frame Reflow</title> |
michael@0 | 14 | </head> |
michael@0 | 15 | <body> |
michael@0 | 16 | <h1>Debugging Frame Reflow HowTo</h1> |
michael@0 | 17 | <h2>General Overview</h2> |
michael@0 | 18 | <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>. |
michael@0 | 19 | It provides the following information for each frame at the |
michael@0 | 20 | start of its reflow |
michael@0 | 21 | <ul> |
michael@0 | 22 | <li>reflow reason |
michael@0 | 23 | <li>available width, available height |
michael@0 | 24 | <li>computed width, computed height |
michael@0 | 25 | <li>the previous and the next frame in flow |
michael@0 | 26 | <li>and a count number. |
michael@0 | 27 | </ul> |
michael@0 | 28 | <p>When the frame's reflow is finished the following information is displayed :</p> |
michael@0 | 29 | <ul> |
michael@0 | 30 | <li>reflow metric (desired) width, height |
michael@0 | 31 | <li>max. element size (MES) width |
michael@0 | 32 | <li>maximum Width |
michael@0 | 33 | <li>frame status |
michael@0 | 34 | <li>overflow area |
michael@0 | 35 | </ul> |
michael@0 | 36 | |
michael@0 | 37 | <h2>Getting the log</h2> |
michael@0 | 38 | <ul> |
michael@0 | 39 | <li>Make sure that your build is a <b>debug</b> build. |
michael@0 | 40 | <li>Create a text file (for instance <code>reflow_rules.txt</code>). |
michael@0 | 41 | <li>Enter this line in the text file <pre>* 1</pre> |
michael@0 | 42 | <li>Save the text file in the <code>%DIST%</code> directory |
michael@0 | 43 | <li>Go to the <code>%DIST%</code> directory |
michael@0 | 44 | <li>enter from command line: <code>set GECKO_DISPLAY_REFLOW_RULES_FILE=reflow_rules.txt</code> |
michael@0 | 45 | <li> Run <code>viewer > logfile.txt</code> and load your testcase. The |
michael@0 | 46 | logfile will contain all the promised information. |
michael@0 | 47 | </ul> |
michael@0 | 48 | <h2>Log File analyis</h2> |
michael@0 | 49 | <p>The logfile for a simple table like</p> |
michael@0 | 50 | <pre> |
michael@0 | 51 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
michael@0 | 52 | <html> |
michael@0 | 53 | <head> |
michael@0 | 54 | <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> |
michael@0 | 55 | </head> |
michael@0 | 56 | <body> |
michael@0 | 57 | <table width="100"> |
michael@0 | 58 | <tbody> |
michael@0 | 59 | <tr> |
michael@0 | 60 | <td>foo</td> |
michael@0 | 61 | </tr> |
michael@0 | 62 | </tbody> |
michael@0 | 63 | </table> |
michael@0 | 64 | </body> |
michael@0 | 65 | </html> |
michael@0 | 66 | </pre> |
michael@0 | 67 | |
michael@0 | 68 | <p> will create the following log:</p> |
michael@0 | 69 | <table class="log"><tr><td> |
michael@0 | 70 | <pre> |
michael@0 | 71 | VP 00B97C30 r=0 a=9180,4470 c=9180,4470 cnt=856 |
michael@0 | 72 | scroll 00B97EE0 r=0 a=9180,4470 c=9180,4470 cnt=857 |
michael@0 | 73 | scroll 00B97EE0 r=0 a=9180,4470 c=9180,4470 cnt=858 |
michael@0 | 74 | canvas 00B97C6C r=0 a=9180,UC c=9180,4470 cnt=859 |
michael@0 | 75 | area 02D7AFE4 r=0 a=9180,UC c=9180,UC cnt=860 |
michael@0 | 76 | text 02D7B150 r=0 a=9180,UC c=UC,UC cnt=861 |
michael@0 | 77 | text 02D7B150 d=0,0 |
michael@0 | 78 | block 02D7B210 r=0 a=9180,UC c=8940,UC cnt=862 |
michael@0 | 79 | block 02D7B210 d=8940,0 |
michael@0 | 80 | area 02D7AFE4 d=9180,120 |
michael@0 | 81 | canvas 00B97C6C d=9180,4470 |
michael@0 | 82 | scroll 00B97EE0 d=9180,4470 |
michael@0 | 83 | scroll 00B97EE0 d=9180,4470 |
michael@0 | 84 | VP 00B97C30 d=9180,4470 |
michael@0 | 85 | VP 00B97C30 r=1 a=9180,4470 c=9180,4470 cnt=863 |
michael@0 | 86 | scroll 00B97EE0 r=1 a=9180,4470 c=9180,4470 cnt=864 |
michael@0 | 87 | scroll 00B97EE0 r=1 a=9180,4470 c=9180,4470 cnt=865 |
michael@0 | 88 | canvas 00B97C6C r=1 a=9180,UC c=9180,4470 cnt=866 |
michael@0 | 89 | area 02D7AFE4 r=1 a=9180,UC c=9180,UC cnt=867 |
michael@0 | 90 | block 02D7B210 r=1 a=9180,UC c=8940,UC cnt=868 |
michael@0 | 91 | text 02D7B3F8 r=0 a=8940,UC c=UC,UC cnt=869 |
michael@0 | 92 | text 02D7B3F8 d=0,0 |
michael@0 | 93 | tblO 02D7B5F0 r=0 a=8940,UC c=0,0 cnt=870 |
michael@0 | 94 | tbl 02D7B7EC r=0 a=8940,UC c=1500,UC cnt=871 |
michael@0 | 95 | rowG 00B984A4 r=0 a=UC,UC c=UC,UC cnt=872 |
michael@0 | 96 | row 02D7BAF8 r=0 a=UC,UC c=UC,UC cnt=873 |
michael@0 | 97 | cell 02D7BC98 r=0 a=UC,UC c=UC,UC cnt=874 |
michael@0 | 98 | block 02D7BCF8 r=0 a=UC,UC c=UC,UC cnt=875 |
michael@0 | 99 | text 02D7BE84 r=0 a=UC,UC c=UC,UC cnt=876 |
michael@0 | 100 | text 02D7BE84 d=300,285 me=300 |
michael@0 | 101 | block 02D7BCF8 d=300,300 me=300 |
michael@0 | 102 | cell 02D7BC98 d=330,330 me=330 |
michael@0 | 103 | row 02D7BAF8 d=UC,330 |
michael@0 | 104 | rowG 00B984A4 d=UC,330 |
michael@0 | 105 | colG 02D7BFB0 r=0 a=UC,UC c=UC,UC cnt=877 |
michael@0 | 106 | col 02D7C0D8 r=0 a=0,0 c=1500,UC cnt=878 |
michael@0 | 107 | col 02D7C0D8 d=0,0 |
michael@0 | 108 | colG 02D7BFB0 d=0,0 |
michael@0 | 109 | rowG 00B984A4 r=2 a=1500,UC c=1500,UC cnt=879 |
michael@0 | 110 | row 02D7BAF8 r=2 a=1500,UC c=1500,UC cnt=880 |
michael@0 | 111 | cell 02D7BC98 r=2 a=1440,UC c=1410,UC cnt=881 |
michael@0 | 112 | block 02D7BCF8 r=2 a=1410,UC c=1410,UC cnt=882 |
michael@0 | 113 | block 02D7BCF8 d=1410,300 |
michael@0 | 114 | cell 02D7BC98 d=1440,330 |
michael@0 | 115 | row 02D7BAF8 d=1500,330 |
michael@0 | 116 | rowG 00B984A4 d=1500,330 |
michael@0 | 117 | colG 02D7BFB0 r=2 a=1500,UC c=1500,UC cnt=883 |
michael@0 | 118 | col 02D7C0D8 r=0 a=0,0 c=1500,UC cnt=884 |
michael@0 | 119 | col 02D7C0D8 d=0,0 |
michael@0 | 120 | colG 02D7BFB0 d=0,0 |
michael@0 | 121 | tbl 02D7B7EC d=1500,390 |
michael@0 | 122 | tblO 02D7B5F0 d=1500,390 |
michael@0 | 123 | text 02D7C130 r=0 a=8940,UC c=UC,UC cnt=885 |
michael@0 | 124 | text 02D7C130 d=0,0 |
michael@0 | 125 | block 02D7B210 d=8940,390 |
michael@0 | 126 | area 02D7AFE4 d=9180,630 |
michael@0 | 127 | canvas 00B97C6C d=9180,4470 |
michael@0 | 128 | scroll 00B97EE0 d=9180,4470 |
michael@0 | 129 | scroll 00B97EE0 d=9180,4470 |
michael@0 | 130 | VP 00B97C30 d=9180,4470 |
michael@0 | 131 | </pre> |
michael@0 | 132 | </td></tr></table> |
michael@0 | 133 | <p> |
michael@0 | 134 | 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> |
michael@0 | 135 | <table> |
michael@0 | 136 | <tr><td>1</td><td>incremental reflow</td></tr> |
michael@0 | 137 | <tr><td>2</td><td>resize reflow</td></tr> |
michael@0 | 138 | <tr><td>3</td><td>style change reflow</td></tr> |
michael@0 | 139 | <tr><td>4</td><td>dirty reflow.</td></tr> |
michael@0 | 140 | </table> |
michael@0 | 141 | |
michael@0 | 142 | <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>). |
michael@0 | 143 | <p> |
michael@0 | 144 | Below this is a line that reads:<p><code class="log">tblO 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 outer table frame is unconstrained. |
michael@0 | 145 | <p> |
michael@0 | 146 | The table cell requires its children to compute the MES. It is reported back from the block as: |
michael@0 | 147 | <p><code class="log">block 02D7BCF8 d=300,300 me=300</code></p> |
michael@0 | 148 | <p>The block max. element size is 300 twips. |
michael@0 | 149 | <p> The second table reflow is started at |
michael@0 | 150 | <p><code class="log">rowG 00B984A4 r=2 a=1500,UC c=1500,UC cnt=879</code></p> |
michael@0 | 151 | <p>where the previous information is used. |
michael@0 | 152 | The block has been required to compute the max. element size only once and it reports now: |
michael@0 | 153 | <p> <code class="log">block 02D7BCF8 d=1410,300</code></p> |
michael@0 | 154 | <p>The block shows the same address as the previous one. |
michael@0 | 155 | <p>Frames with children that overflow the parent will return <code>PR_TRUE</code> from <code>HasOverflowRect()</code>. For these frames |
michael@0 | 156 | 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. |
michael@0 | 157 | <p> The reflow finishes at the same level where it started. |
michael@0 | 158 | |
michael@0 | 159 | <h2>Advanced reflow debugging</h2> |
michael@0 | 160 | <p>The previously described technique dumps the data for every frame. Sometimes the log is clearer if only the main frames are shown. |
michael@0 | 161 | 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> |
michael@0 | 162 | <table cellspacing="5"> |
michael@0 | 163 | <tr><th style="text-align:left">short name</th><th style="text-align:left">layout tag</th></tr> |
michael@0 | 164 | <tr><td>area</td><td>area</td></tr> |
michael@0 | 165 | <tr><td>block</td><td>block</td></tr> |
michael@0 | 166 | <tr><td>br</td><td>br</td></tr> |
michael@0 | 167 | <tr><td>bullet</td><td>bullet</td></tr> |
michael@0 | 168 | <tr><td>button</td><td>gfxButtonControl</td></tr> |
michael@0 | 169 | <tr><td>hr</td><td>hr</td></tr> |
michael@0 | 170 | <tr><td>frameI</td><td>htmlFrameInner</td></tr> |
michael@0 | 171 | <tr><td>frameO</td><td>htmlFrameOuter</td></tr> |
michael@0 | 172 | <tr><td>img</td><td>image</td></tr> |
michael@0 | 173 | <tr><td>inline</td><td>inline</td></tr> |
michael@0 | 174 | <tr><td>letter</td><td>letter</td></tr> |
michael@0 | 175 | <tr><td>line</td><td>line</td></tr> |
michael@0 | 176 | <tr><td>select</td><td>select</td></tr> |
michael@0 | 177 | <tr><td>obj</td><td>object</td></tr> |
michael@0 | 178 | <tr><td>page</td><td>page</td></tr> |
michael@0 | 179 | <tr><td>place</td><td>placeholder</td></tr> |
michael@0 | 180 | <tr><td>canvas</td><td>canvas</td></tr> |
michael@0 | 181 | <tr><td>root</td><td>root</td></tr> |
michael@0 | 182 | <tr><td>scroll</td><td>scroll</td></tr> |
michael@0 | 183 | <tr><td>caption</td><td>tableCaption</td></tr> |
michael@0 | 184 | <tr><td>cell</td><td>tableCell</td></tr> |
michael@0 | 185 | <tr><td>bcCell</td><td>bcTableCell</td></tr> |
michael@0 | 186 | <tr><td>col</td><td>tableCol</td></tr> |
michael@0 | 187 | <tr><td>colG</td><td>tableColGroup</td></tr> |
michael@0 | 188 | <tr><td> tbl</td><td>table</td></tr> |
michael@0 | 189 | <tr><td>tblO</td><td>tableOuter</td></tr> |
michael@0 | 190 | <tr><td>rowG</td><td>tableRowGroup</td></tr> |
michael@0 | 191 | <tr><td>row</td><td>tableRow</td></tr> |
michael@0 | 192 | <tr><td>textCtl</td><td>textInput</td></tr> |
michael@0 | 193 | <tr><td>text</td><td>text</td></tr> |
michael@0 | 194 | <tr><td>VP</td><td>viewport</td></tr> |
michael@0 | 195 | </table> |
michael@0 | 196 | <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 |
michael@0 | 197 | the reflow tree. |
michael@0 | 198 | |
michael@0 | 199 | <h2>Other reflow debug options</h2> |
michael@0 | 200 | |
michael@0 | 201 | <h3>GECKO_DISPLAY_REFLOW_FLAG_PIXEL_ERRORS</h3> |
michael@0 | 202 | <p> |
michael@0 | 203 | 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. |
michael@0 | 204 | <table class="log"><tr><td> |
michael@0 | 205 | <pre> |
michael@0 | 206 | row 0268A594 r=0 a=UC,UC c=UC,20 cnt=870 |
michael@0 | 207 | VALUE 20 is not a whole pixel |
michael@0 | 208 | cell 0268A6C0 r=0 a=UC,UC c=UC,15 cnt=871 |
michael@0 | 209 | block 0268A764 r=0 a=UC,UC c=UC,UC cnt=872 |
michael@0 | 210 | block 0268A764 d=0,0 me=0 |
michael@0 | 211 | cell 0268A6C0 d=0,0 me=0 |
michael@0 | 212 | row 0268A594 d=UC,20 |
michael@0 | 213 | VALUE 20 is not a whole pixel |
michael@0 | 214 | rowG 0268A02C d=UC,695 |
michael@0 | 215 | VALUE 695 is not a whole pixel</pre> |
michael@0 | 216 | </td></tr></table> |
michael@0 | 217 | <p> |
michael@0 | 218 | 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. |
michael@0 | 219 | |
michael@0 | 220 | <h3>GECKO_DISPLAY_REFLOW_INDENT_UNDISPLAYED_FRAMES</h3> |
michael@0 | 221 | <p> |
michael@0 | 222 | 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. |
michael@0 | 223 | </body> |
michael@0 | 224 | </html> |