diff options
author | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-03 20:45:58 +0000 |
---|---|---|
committer | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-03 20:45:58 +0000 |
commit | ab3c20b28bf4712dffb4ae38d0d7762f71842a69 (patch) | |
tree | 0ec3782fe8039cdf0bbc605dcf7f53c01cc983c4 | |
parent | e354ca4f379346b0a372432265f7aab47a1155b7 (diff) | |
download | chromium_src-ab3c20b28bf4712dffb4ae38d0d7762f71842a69.zip chromium_src-ab3c20b28bf4712dffb4ae38d0d7762f71842a69.tar.gz chromium_src-ab3c20b28bf4712dffb4ae38d0d7762f71842a69.tar.bz2 |
about:gpu support for thread name metadata.
Review URL: http://codereview.chromium.org/7495036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95307 0039d316-1c4b-4281-b951-d872f2087c98
7 files changed, 209 insertions, 59 deletions
diff --git a/chrome/browser/resources/gpu_internals.js b/chrome/browser/resources/gpu_internals.js index fcc60c8..57832f0 100644 --- a/chrome/browser/resources/gpu_internals.js +++ b/chrome/browser/resources/gpu_internals.js @@ -16,7 +16,6 @@ var browserBridge; var tracingController; -var timelineView; // made global for debugging purposes only var profilingView; // made global for debugging purposes only /** diff --git a/chrome/browser/resources/gpu_internals/timeline.css b/chrome/browser/resources/gpu_internals/timeline.css index 55857c4..2225831 100644 --- a/chrome/browser/resources/gpu_internals/timeline.css +++ b/chrome/browser/resources/gpu_internals/timeline.css @@ -36,7 +36,7 @@ found in the LICENSE file. .timeline-slice-track-title { text-align: right; overflow: visible; - width: 150px; + width: 300px; padding-right: 5px; } diff --git a/chrome/browser/resources/gpu_internals/timeline.js b/chrome/browser/resources/gpu_internals/timeline.js index e136f31..79305cb 100644 --- a/chrome/browser/resources/gpu_internals/timeline.js +++ b/chrome/browser/resources/gpu_internals/timeline.js @@ -208,6 +208,7 @@ cr.define('gpu', function() { // Create tracks. this.tracks_.textContent = ''; var threads = model.getAllThreads(); + threads.sort(gpu.TimelineThread.compare); for (var tI = 0; tI < threads.length; tI++) { var thread = threads[tI]; var track = new TimelineThreadTrack(); diff --git a/chrome/browser/resources/gpu_internals/timeline_model.js b/chrome/browser/resources/gpu_internals/timeline_model.js index eeb0cb9..a92d6ac 100644 --- a/chrome/browser/resources/gpu_internals/timeline_model.js +++ b/chrome/browser/resources/gpu_internals/timeline_model.js @@ -65,6 +65,11 @@ cr.define('gpu', function() { } TimelineThread.prototype = { + /** + * Name of the thread, if present. + */ + name: undefined, + getSubrow: function(i) { while (i >= this.subRows.length) this.subRows.push([]); @@ -83,11 +88,26 @@ cr.define('gpu', function() { this.nonNestedSubRows.push([slice]); }, + /** + * Updates the minTimestamp and maxTimestamp fields based on the + * current slices and nonNestedSubRows attached to the thread. + */ updateBounds: function() { - var slices = this.subRows[0]; - if (slices.length != 0) { - this.minTimestamp = slices[0].start; - this.maxTimestamp = slices[slices.length - 1].end; + var values = []; + var slices; + if (this.subRows[0].length != 0) { + slices = this.subRows[0]; + values.push(slices[0].start); + values.push(slices[slices.length - 1].end); + } + for (var i = 0; i < this.nonNestedSubRows.length; ++i) { + slices = this.nonNestedSubRows[i]; + values.push(slices[0].start); + values.push(slices[slices.length - 1].end); + } + if (values.length) { + this.minTimestamp = Math.min.apply(Math, values); + this.maxTimestamp = Math.max.apply(Math, values); } else { this.minTimestamp = undefined; this.maxTimestamp = undefined; @@ -97,6 +117,30 @@ cr.define('gpu', function() { }; /** + * Comparison between threads that orders first by pid, + * then by names, then by tid. + */ + TimelineThread.compare = function(x,y) { + if(x.parent.pid != y.parent.pid) { + return x.parent.pid - y.parent.pid; + } + + if (x.name && y.name) { + var tmp = x.name.localeCompare(y.name); + if (tmp == 0) + return x.tid - y.tid; + return tmp; + } else if (x.name) { + return -1; + } else if (y.name){ + return 1; + } else { + return x.tid - y.tid; + } + }; + + + /** * The TimelineProcess represents a single process in the * trace. Right now, we keep this around purely for bookkeeping * reasons. @@ -123,6 +167,7 @@ cr.define('gpu', function() { */ function TimelineModel(events) { this.processes = {}; + this.importErrors = []; if (events) this.importEvents(events); @@ -144,7 +189,7 @@ cr.define('gpu', function() { importEvents: function(events) { // A ptid is a pid and tid joined together x:y fashion, eg 1024:130 // The ptid is a unique key for a thread in the trace. - + this.importErrors = []; // Threadstate const numColorIds = 30; @@ -185,7 +230,7 @@ cr.define('gpu', function() { for (var x in event.args) sliceID += ';' + event.args[x]; if (state.openNonNestedSlices[sliceID]) - console.log('Event ' + sliceID + ' already open.'); + this.importErrors.push('Event ' + sliceID + ' already open.'); state.openNonNestedSlices[sliceID] = slice; } else { state.openSlices.push(slice); @@ -250,12 +295,19 @@ cr.define('gpu', function() { // TimelineSliceTrack's redraw() knows how to handle this. processBegin(state, event); processEnd(state, event); + } else if (event.ph == 'M') { + if (event.name == 'thread_name') { + var thread = this.getProcess(event.pid).getThread(event.tid); + thread.name = event.args.name; + } else { + this.importErrors.push('Unrecognized metadata name: ' + event.name); + } } else { - throw new Error('Unrecognized event phase: ' + event.ph + + this.importErrors.push('Unrecognized event phase: ' + event.ph + '(' + event.name + ')'); } } - + this.pruneEmptyThreads(); this.updateBounds(); // Add end events for any events that are still on the stack. These @@ -289,6 +341,22 @@ cr.define('gpu', function() { this.maxTimestamp = this.maxTimestamp + boost; }, + /** + * Removes threads from the model that have no subrows. + */ + pruneEmptyThreads: function() { + for (var pid in this.processes) { + var process = this.processes[pid]; + var prunedThreads = []; + for (var tid in process.threads) { + var thread = process.threads[tid]; + if (thread.subRows[0].length || thread.nonNestedSubRows.legnth) + prunedThreads.push(thread); + } + process.threads = prunedThreads; + } + }, + updateBounds: function() { var wmin = Infinity; var wmax = -wmin; @@ -296,7 +364,8 @@ cr.define('gpu', function() { for (var tI = 0; tI < threads.length; tI++) { var thread = threads[tI]; thread.updateBounds(); - if (thread.minTimestamp && thread.maxTimestamp) { + if (thread.minTimestamp != undefined && + thread.maxTimestamp != undefined) { wmin = Math.min(wmin, thread.minTimestamp); wmax = Math.max(wmax, thread.maxTimestamp); } diff --git a/chrome/browser/resources/gpu_internals/timeline_test.html b/chrome/browser/resources/gpu_internals/timeline_test.html new file mode 100644 index 0000000..f8a1218 --- /dev/null +++ b/chrome/browser/resources/gpu_internals/timeline_test.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<!-- +Copyright (c) 2010 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<html> +<head> +<title></title> +<link rel="stylesheet" href="timeline.css"> +<!--<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>--> +<script src="../shared/js/cr.js"></script> +<script src="../shared/js/cr/event_target.js"></script> +<script src="../shared/js/cr/ui.js"></script> +<script src="fast_rect_renderer.js"></script> +<script src="tracing_controller_tests.js"></script> +<script src="sorted_array_utils.js"></script> +<script src="timeline.js"></script> +<script src="timeline_track.js"></script> +<script src="timeline_model.js"></script> +<!-- +<script> + +goog.require('goog.testing.jsunit'); + +</script> +--> +</head> +<body> +<div id="sandbox"></div> +<script> + +var sandbox = document.getElementById('sandbox'); +var timeline; + +function testTimeline() { + model = new gpu.TimelineModel(); + model.importEvents(tracingControllerDataSets); + timeline = new gpu.Timeline(); + timeline.model = model; + sandbox.appendChild(timeline); +} +document.addEventListener('DOMContentLoaded', testTimeline); +</script> + +</body> +</html> diff --git a/chrome/browser/resources/gpu_internals/timeline_track.js b/chrome/browser/resources/gpu_internals/timeline_track.js index 464e0eb..34db08d 100644 --- a/chrome/browser/resources/gpu_internals/timeline_track.js +++ b/chrome/browser/resources/gpu_internals/timeline_track.js @@ -132,8 +132,12 @@ cr.define('gpu', function() { addTrack(this, this.thread_.subRows[srI]); } if (this.tracks_.length > 0) { + var tname = this.thread_.name || this.thread_.tid; this.tracks_[0].heading = this.thread_.parent.pid + ': ' + - this.thread_.tid + ': '; + tname + ':'; + this.tracks_[0].tooltip = 'pid: ' + this.thread_.parent.pid + + ', tid: ' + this.thread_.tid + + (this.thread_.name ? ', name: ' + this.thread_.name : ''); } } }, @@ -194,9 +198,9 @@ cr.define('gpu', function() { this.className = 'timeline-slice-track'; this.slices_ = null; - this.titleDiv_ = document.createElement('div'); - this.titleDiv_.className = 'timeline-slice-track-title'; - this.appendChild(this.titleDiv_); + this.headingDiv_ = document.createElement('div'); + this.headingDiv_.className = 'timeline-slice-track-title'; + this.appendChild(this.headingDiv_); this.canvasContainer_ = document.createElement('div'); this.canvasContainer_.className = 'timeline-slice-track-canvas-container'; @@ -209,7 +213,11 @@ cr.define('gpu', function() { }, set heading(text) { - this.titleDiv_.textContent = text; + this.headingDiv_.textContent = text; + }, + + set tooltip(text) { + this.headingDiv_.title = text; }, set slices(slices) { @@ -325,7 +333,7 @@ cr.define('gpu', function() { if (slice.duration > quickDiscardThresshold) { var title = slice.title; if (slice.didNotFinish) { - title += " (Did Not Finish)"; + title += ' (Did Not Finish)'; } function labelWidth() { return quickMeasureText(ctx, title) + 2; diff --git a/chrome/browser/resources/gpu_internals/tracing_controller_tests.js b/chrome/browser/resources/gpu_internals/tracing_controller_tests.js index 9c7cc65..dc791c9 100644 --- a/chrome/browser/resources/gpu_internals/tracing_controller_tests.js +++ b/chrome/browser/resources/gpu_internals/tracing_controller_tests.js @@ -8,6 +8,15 @@ cr.define('gpu', function() { events_url: "./tests/big_trace.json" }, { + name: "trivial_trace", + events: [ + {"name":"a","args":{},"pid":52,"ts":9524,"cat":"foo","tid":53,"ph":"B"}, + {"name":"a","args":{},"pid":52,"ts":9560,"cat":"foo","tid":53,"ph":"E"}, + {"name":"b","args":{},"pid":52,"ts":9629,"cat":"foo","tid":53,"ph":"B"}, + {"name":"b","args":{},"pid":52,"ts":9631,"cat":"foo","tid":53,"ph":"E"} + ] + }, + { name: "simple_trace", events: [ {"cat":"PERF","pid":22630,"tid":22630,"ts":826,"ph":"B", @@ -46,14 +55,23 @@ cr.define('gpu', function() { {"cat":"PERF","pid":22630,"tid":22631,"ts":845,"ph":"I", "name":"I4","args":{}}, {"cat":"PERF","pid":22630,"tid":22631,"ts":854,"ph":"E", - "name":"A","args":{}} + "name":"A","args":{}}, + + {"cat":"__metadata","pid":22630,"tid":22630,"ts":0,"ph":"M", + "name":"thread_name","args":{"name": "threadA"}}, + {"cat":"__metadata","pid":22630,"tid":22631,"ts":0,"ph":"M", + "name":"thread_name","args":{"name": "threadB"}}, + {"cat":"__metadata","pid":22630,"tid":22632,"ts":0,"ph":"M", + "name":"thread_name","args":{"name": "threadC"}} ] }, { name: "nonnested_trace", events: [ - {'cat':'PERF','pid':22630,'tid':22630,'ts':826,'ph':'B','name':'A','args':{}}, - {'cat':'PERF','pid':22630,'tid':22630,'ts':827,'ph':'B','name':'Asub','args':{}}, + {'cat':'PERF','pid':22630,'tid':22630,'ts':826,'ph':'B', + 'name':'A','args':{}}, + {'cat':'PERF','pid':22630,'tid':22630,'ts':827,'ph':'B', + 'name':'Asub','args':{}}, {'cat':'PERF','pid':22630,'tid':22630,'ts':829,'ph':'B', 'name':'NonNest','args':{'id':'1','ui-nest':'0'}}, {'cat':'PERF','pid':22630,'tid':22630,'ts':830,'ph':'B', @@ -64,66 +82,74 @@ cr.define('gpu', function() { 'name':'NonNest','args':{'id':'1','ui-nest':'0'}}, {'cat':'PERF','pid':22630,'tid':22630,'ts':833,'ph':'E', 'name':'NonNest','args':{'id':'2','ui-nest':'0'}}, - {'cat':'PERF','pid':22630,'tid':22630,'ts':834,'ph':'E','name':'A','args':{}}, + {'cat':'PERF','pid':22630,'tid':22630,'ts':834,'ph':'E', + 'name':'A','args':{}}, - {'cat':'PERF','pid':22630,'tid':22631,'ts':827,'ph':'B','name':'A','args':{}}, - {'cat':'PERF','pid':22630,'tid':22631,'ts':854,'ph':'E','name':'A','args':{}} + {'cat':'PERF','pid':22630,'tid':22631,'ts':827,'ph':'B', + 'name':'A','args':{}}, + {'cat':'PERF','pid':22630,'tid':22631,'ts':854,'ph':'E', + 'name':'A','args':{}} ] }, { name: "tall_trace", events: [ - {"cat":"PERF","pid":22630,"tid":22630,"ts":826,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22630,"ts":827,"ph":"B","name":"Asub","args":{}}, - {"cat":"PERF","pid":22630,"tid":22630,"ts":828,"ph":"E","name":"Asub","args":{}}, - {"cat":"PERF","pid":22630,"tid":22630,"ts":829,"ph":"B","name":"Asub","args":{}}, - {"cat":"PERF","pid":22630,"tid":22630,"ts":832,"ph":"E","name":"Asub","args":{}}, - {"cat":"PERF","pid":22630,"tid":22630,"ts":833,"ph":"E","name":"","args":{}}, + {"cat":"X","pid":30,"tid":30,"ts":826,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":30,"ts":827,"ph":"B","name":"Asub","args":{}}, + {"cat":"X","pid":30,"tid":30,"ts":828,"ph":"E","name":"Asub","args":{}}, + {"cat":"X","pid":30,"tid":30,"ts":829,"ph":"B","name":"Asub","args":{}}, + {"cat":"X","pid":30,"tid":30,"ts":832,"ph":"E","name":"Asub","args":{}}, + {"cat":"X","pid":30,"tid":30,"ts":833,"ph":"E","name":"","args":{}}, + + {"cat":"X","pid":30,"tid":31,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":31,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22631,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22631,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":32,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":32,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22632,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22632,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":33,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":33,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22633,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22633,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":34,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":34,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22634,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22634,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":35,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":35,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22635,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22635,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":36,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":36,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22636,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22636,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":37,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":37,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22637,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22637,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":38,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":38,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22638,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22638,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":39,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":39,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22639,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22639,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":10,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":10,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22610,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22610,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":31,"tid":11,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":31,"tid":11,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22611,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22611,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":12,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":12,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22612,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22612,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":13,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":13,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22613,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22613,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":14,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":14,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22614,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22614,"ts":848,"ph":"E","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":15,"ts":840,"ph":"B","name":"A","args":{}}, + {"cat":"X","pid":30,"tid":15,"ts":848,"ph":"E","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22615,"ts":840,"ph":"B","name":"A","args":{}}, - {"cat":"PERF","pid":22630,"tid":22615,"ts":848,"ph":"E","name":"A","args":{}} + {"cat":"__metadata","pid":30,"tid":14,"ts":0,"ph":"M", + "name":"thread_name","args":{"name": "threadB"}}, + {"cat":"__metadata","pid":30,"tid":15,"ts":0,"ph":"M", + "name":"thread_name","args":{"name": "threadA"}} ] }, { |