OSDN Git Service

inferno: support building embedded flamegraph.
authorYabin Cui <yabinc@google.com>
Mon, 25 Sep 2017 22:54:45 +0000 (15:54 -0700)
committerYabin Cui <yabinc@google.com>
Tue, 26 Sep 2017 00:01:08 +0000 (17:01 -0700)
This is to show embedded flamegraph with other view in a report html.

Bug: http://b/66914187
Test: run inferno.sh manually.

Change-Id: Ib68b7dcbd41d85d1fb47f1637407e50bd7e93d87

simpleperf/scripts/inferno/inferno.py
simpleperf/scripts/inferno/script.js
simpleperf/scripts/inferno/svg_renderer.py

index 5060a35..c18a2d1 100644 (file)
@@ -141,13 +141,14 @@ def output_report(process, args):
     """
     f = open(args.report_path, 'w')
     filepath = os.path.realpath(f.name)
-    f.write("<html>")
-    f.write("<head>")
-    f.write("""<style type="text/css">""")
-    f.write(get_local_asset_content(os.path.join("jqueryui", "jquery-ui.min.css")))
-    f.write("</style>")
-    f.write("</head>")
-    f.write("<body style='font-family: Monospace;' onload='init()'>")
+    if not args.embedded_flamegraph:
+        f.write("<html><body>")
+    f.write("<div id='flamegraph_id' style='font-family: Monospace; %s'>" % (
+            "display: none;" if args.embedded_flamegraph else ""))
+    if not args.embedded_flamegraph:
+        f.write("""<style type="text/css">""")
+        f.write(get_local_asset_content(os.path.join("jqueryui", "jquery-ui.min.css")))
+        f.write("</style>")
     f.write("""<style type="text/css"> .s { stroke:black; stroke-width:0.5; cursor:pointer;}
             </style>""")
     f.write('<style type="text/css"> .t:hover { cursor:pointer; } </style>')
@@ -182,11 +183,14 @@ def output_report(process, args):
     f.write("</div>")
     f.write("""<br/><br/>
             <div>Navigate with WASD, zoom in with SPACE, zoom out with BACKSPACE.</div>""")
-    f.write("<script>")
-    f.write(get_local_asset_content(os.path.join("jqueryui", "jquery-3.2.1.min.js")))
-    f.write(get_local_asset_content(os.path.join("jqueryui", "jquery-ui.min.js")))
-    f.write("</script>")
+    if not args.embedded_flamegraph:
+        f.write("<script>")
+        f.write(get_local_asset_content(os.path.join("jqueryui", "jquery-3.2.1.min.js")))
+        f.write(get_local_asset_content(os.path.join("jqueryui", "jquery-ui.min.js")))
+        f.write("</script>")
     f.write("<script>%s</script>" % get_local_asset_content("script.js"))
+    if not args.embedded_flamegraph:
+        f.write("<script> $(document).ready(flamegraphInit); </script>")
 
     # Output tid == pid Thread first.
     main_thread = [x for x in process.threads.values() if x.tid == process.pid]
@@ -201,8 +205,9 @@ def output_report(process, args):
                 thread.tid, thread.name, thread.num_samples))
         renderSVG(thread.flamegraph, f, args.color, args.svg_width)
 
-    f.write("</body>")
-    f.write("</html>")
+    f.write("</div>")
+    if not args.embedded_flamegraph:
+        f.write("</body></html")
     f.close()
     return "file://" + filepath
 
@@ -273,6 +278,9 @@ def main():
     parser.add_argument('--disable_adb_root', action='store_true', help="""Force adb to run in non
                         root mode.""")
     parser.add_argument('-o', '--report_path', default='report.html', help="Set report path.")
+    parser.add_argument('--embedded_flamegraph', action='store_true', help="""
+                        Generate embedded flamegraph.""")
+    parser.add_argument('--no_browser', action='store_true', help="Don't open report in browser.")
     args = parser.parse_args()
     process = Process("", 0)
 
@@ -294,9 +302,10 @@ def main():
     parse_samples(process, args)
     generate_threads_offsets(process)
     report_path = output_report(process, args)
-    open_report_in_browser(report_path)
+    if not args.no_browser:
+        open_report_in_browser(report_path)
 
-    log_info("Report generated at '%s'." % report_path)
+    log_info("Flamegraph generated at '%s'." % report_path)
 
 if __name__ == "__main__":
     main()
index 834504a..d3033c2 100644 (file)
@@ -1,10 +1,16 @@
 'use strict';
 
-function init() {
-  let x = document.getElementsByTagName('svg');
-  for (let i = 0; i < x.length; i++) {
-      createZoomHistoryStack(x[i]);
-  }
+function flamegraphInit() {
+  $("div#flamegraph_id svg").each(function (_, element) {
+    createZoomHistoryStack(element);
+    adjust_text_size(element);
+  });
+  $("div#flamegraph_id .flamegraph_block").resizable({
+    handles: "e",
+    resize: function(event, ui) {
+      adjust_text_size(ui.element.find("svg")[0]);
+    }
+  });
 }
 
 // Create a stack add the root svg element in it.
@@ -31,8 +37,8 @@ function adjust_node_text_size(x, svgWidth) {
 
   // Don't even bother trying to find a best fit. The area is too small.
   if (width < 28) {
-      text.textContent = '';
-      return;
+    text.textContent = '';
+    return;
   }
   // Remove dso and #samples which are here only for mouseover purposes.
   let methodName = title.textContent.split(' | ')[0];
@@ -222,7 +228,7 @@ function select(e) {
   let info = method_and_info[1];
 
   // Parse info
-  // '/system/lib64/libhwbinder.so (4 samples: 0.28%)'
+  // '/system/lib64/libhwbinder.so (4 events: 0.28%)'
   let regexp = /(.*) \(.* ([0-9**\.[0-9]*%)\)/g;
   let match = regexp.exec(info);
   if (match.length > 2) {
@@ -236,13 +242,4 @@ function select(e) {
   // Set fields
   let barTextElement = selected.ownerSVGElement.getElementById('info_text');
   barTextElement.textContent = methodName;
-}
-
-$(document).ready(function() {
-  $(".flamegraph_block").resizable({
-    handles: "e",
-    resize: function(event, ui) {
-      adjust_text_size(ui.element.find("svg")[0]);
-    }
-  });
-});
\ No newline at end of file
+}
\ No newline at end of file
index 3950572..45c987b 100644 (file)
@@ -169,7 +169,7 @@ def renderSVG(flamegraph, f, color_scheme, width):
     f.write("""<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
     width="100%%" height="100%%" style="border: 1px solid black;"
-    onload="adjust_text_size(this);" rootid="%d">
+    rootid="%d">
     """ % (flamegraph.children[0].id))
     f.write("""<defs > <linearGradient id="background_gradiant" y1="0" y2="1" x1="0" x2="0" >
     <stop stop-color="#eeeeee" offset="5%" /> <stop stop-color="#efefb1" offset="90%" />