frame_reflow_debug.html 10 KB

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