| <html> |
| <!-- |
| This HTML file is the swingp visualizer. |
| |
| The basic architecture is based on a cooperative multithreading model, with the two functional units as follows: |
| 1) An HTTP long-poller that polls Studio for swingp render stats. |
| * Each fetch may return one or more swingp frame renders containing multiple threads. |
| * The data is encoded via a simple bytes_length + content_bytes[bytes_length] encoding. |
| * Each content_bytes[bytes_length] is a complete JSON tree structure, in the pattern of [ThreadStat+]. |
| * During processing of each ThreadStat, rectangles are generated for rendered components' bounds, and frame bounds are (perhaps) updated. |
| 2) A render loop that takes the rectangles and bounds generated/updated in the poller functional unit, and renders them to the canvas. |
| * The canvas is hardcoded to render at 1/4 of Swing's resolution. |
| * The 1/4 resolution might not be suitable for high DPI displays -- one can change the frameScale and reload the page. |
| * Each rectangle is re-rendered according to a time-based alpha decay. |
| * Rectangles' alpha are tied to the parent JSON render tree's lifetime (so all rectangles generated by a single JSON tree shares alpha). |
| * Primary (main window) is rendered in green, and secondary (popups and other heavy weight components on top) are rendered in red. |
| --> |
| |
| <head> |
| <script type="text/javascript" src="Visualizer.js"></script> |
| <script type="text/javascript" src="SwingPPoller.js"></script> |
| <script type="text/javascript" src="FrameManager.js"></script> |
| <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> |
| <script type="text/javascript"> |
| var poller; |
| var visualizer; |
| window.onload = function () { |
| poller = new SwingPPoller(false); |
| visualizer = new Visualizer(document.getElementById("canvas"), |
| document.getElementById("root_filter_element"), |
| document.getElementById("components_rendered")); |
| frameManager = new FrameManager(document.getElementById("perf_chart"), document.getElementById("frame_tree_canvas")); |
| poller.addInputHandler(visualizer.processInput); |
| poller.addInputHandler(frameManager.processInput); |
| setInterval(() => { |
| visualizer.draw(); |
| frameManager.draw(); |
| }, 17); |
| } |
| function resizeCanvas() { |
| document.getElementById("canvas").width = window.innerWidth; |
| document.getElementById("frame_tree_canvas").width = window.innerWidth; |
| } |
| </script> |
| </head> |
| |
| <body onresize="resizeCanvas()"> |
| <form> |
| <fieldset> |
| <legend>Render:</legend> |
| Filter Root: <input type="text" id="root_filter_element" placeholder="e.g. SomeAwtOrSwingComponentType"><br> |
| <p id="components_rendered"></p> |
| <canvas id="canvas" /> |
| </fieldset> |
| <fieldset> |
| <legend>Frames:</legend> |
| Cached Frames: <input type="range" min="10" max="250" value="75" class="slider" id="cahced_frames_element" |
| oninput="frameManager.setMaxFrames(this.value)" onchange="frameManager.setMaxFrames(this.value)"><br /> |
| Pause: <input type="checkbox" onclick="frameManager.togglePause()" /> |
| <div id="perf_chart"></div> |
| <canvas id="frame_tree_canvas" /> |
| </fieldset> |
| </form> |
| </body> |
| |
| </html> |