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