diff options
author | jbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-18 22:12:18 +0000 |
---|---|---|
committer | jbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-18 22:12:18 +0000 |
commit | c3f3840beeeba4bdead501e8ded1df7177eaa8af (patch) | |
tree | ff7eef3d1bdab4b7a64309772ebb30b5078bd288 | |
parent | 6b15434bf59bad3c5fe1f632adcc49746b23aaed (diff) | |
download | chromium_src-c3f3840beeeba4bdead501e8ded1df7177eaa8af.zip chromium_src-c3f3840beeeba4bdead501e8ded1df7177eaa8af.tar.gz chromium_src-c3f3840beeeba4bdead501e8ded1df7177eaa8af.tar.bz2 |
Add support for non-nested trace events.
Trace events that start with "*" are treated as non-nested, so opening and closing events are matched by name and args, not with a stack. They're also displayed in a separate set of subrows apart from normal events. This allows for long-running processes that occur during several function calls to be displayed.
Some events to track GPU process throttling have also been added using this mechanism.
BUG=79800
TEST=
Review URL: http://codereview.chromium.org/6873003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85824 0039d316-1c4b-4281-b951-d872f2087c98
3 files changed, 100 insertions, 32 deletions
diff --git a/chrome/browser/resources/gpu_internals/timeline_model.js b/chrome/browser/resources/gpu_internals/timeline_model.js index 848308d..0cb9b90 100644 --- a/chrome/browser/resources/gpu_internals/timeline_model.js +++ b/chrome/browser/resources/gpu_internals/timeline_model.js @@ -51,7 +51,8 @@ cr.define('gpu', function() { /** * A TimelineThread stores all the trace events collected for a particular * thread. We organize the slices on a thread by "subrows," where subrow 0 - * has all the root slices, subrow 1 those nested 1 deep, and so on. + * has all the root slices, subrow 1 those nested 1 deep, and so on. There + * is also a set of non-nested subrows. * * @constructor */ @@ -59,6 +60,7 @@ cr.define('gpu', function() { this.parent = parent; this.tid = tid; this.subRows = [[]]; + this.nonNestedSubRows = []; } TimelineThread.prototype = { @@ -68,6 +70,18 @@ cr.define('gpu', function() { return this.subRows[i]; }, + addNonNestedSlice: function(slice) { + for (var i = 0; i < this.nonNestedSubRows.length; i++) { + var currSubRow = this.nonNestedSubRows[i]; + var lastSlice = currSubRow[currSubRow.length - 1]; + if (slice.start >= lastSlice.start + lastSlice.duration) { + currSubRow.push(slice); + return; + } + } + this.nonNestedSubRows.push([slice]); + }, + updateBounds: function() { var slices = this.subRows[0]; if (slices.length != 0) { @@ -135,6 +149,7 @@ cr.define('gpu', function() { const numColorIds = 12; function ThreadState(tid) { this.openSlices = []; + this.openNonNestedSlices = {}; } var threadStateByPTID = {}; @@ -163,24 +178,49 @@ cr.define('gpu', function() { var colorId = getColor(event.name); var slice = new TimelineSlice(event.name, colorId, event.ts, event.args); - state.openSlices.push(slice); + if (event.args['ui-nest'] === '0') { + var sliceID = event.name; + for (var x in event.args) { + sliceID += ';' + event.args[x]; + } + if (state.openNonNestedSlices[sliceID]) + console.log('Event ' + sliceID + ' already open.'); + state.openNonNestedSlices[sliceID] = slice; + } else + state.openSlices.push(slice); } else if (event.ph == 'E') { - if (state.openSlices.length == 0) { - // Ignore E events that that are unmatched. - continue; - } - var slice = state.openSlices.pop(); - slice.duration = event.ts - slice.start; - - // Store the slice on the right subrow. - var thread = this.getProcess(event.pid).getThread(event.tid); - var subRowIndex = state.openSlices.length; - thread.getSubrow(subRowIndex).push(slice); - - // Add the slice to the subSlices array of its parent. - if (state.openSlices.length) { - var parentSlice = state.openSlices[state.openSlices.length - 1]; - parentSlice.subSlices.push(slice); + if (event.args['ui-nest'] === '0') { + var sliceID = event.name; + for (var x in event.args) { + sliceID += ';' + event.args[x]; + } + var slice = state.openNonNestedSlices[sliceID]; + if (!slice) + continue; + slice.duration = event.ts - slice.start; + + // Store the slice in a non-nested subrow. + var thread = this.getProcess(event.pid).getThread(event.tid); + thread.addNonNestedSlice(slice); + delete state.openNonNestedSlices[name]; + } else { + if (state.openSlices.length == 0) { + // Ignore E events that that are unmatched. + continue; + } + var slice = state.openSlices.pop(); + slice.duration = event.ts - slice.start; + + // Store the slice on the right subrow. + var thread = this.getProcess(event.pid).getThread(event.tid); + var subRowIndex = state.openSlices.length; + thread.getSubrow(subRowIndex).push(slice); + + // Add the slice to the subSlices array of its parent. + if (state.openSlices.length) { + var parentSlice = state.openSlices[state.openSlices.length - 1]; + parentSlice.subSlices.push(slice); + } } } else if (event.ph == 'I') { // TODO(nduca): Implement parsing of immediate events. @@ -218,13 +258,18 @@ cr.define('gpu', function() { var threads = this.getAllThreads(); for (var tI = 0; tI < threads.length; tI++) { var thread = threads[tI]; - for (var tSR = 0; tSR < thread.subRows.length; tSR++) { - var subRow = thread.subRows[tSR]; + var shiftSubRow = function(subRow) { for (var tS = 0; tS < subRow.length; tS++) { var slice = subRow[tS]; slice.start = (slice.start - timeBase) / 1000; slice.duration /= 1000; } + }; + for (var tSR = 0; tSR < thread.subRows.length; tSR++) { + shiftSubRow(thread.subRows[tSR]); + } + for (var tSR = 0; tSR < thread.nonNestedSubRows.length; tSR++) { + shiftSubRow(thread.nonNestedSubRows[tSR]); } } diff --git a/chrome/browser/resources/gpu_internals/timeline_track.js b/chrome/browser/resources/gpu_internals/timeline_track.js index 2c86967..fe582e0 100644 --- a/chrome/browser/resources/gpu_internals/timeline_track.js +++ b/chrome/browser/resources/gpu_internals/timeline_track.js @@ -48,6 +48,17 @@ cr.define('gpu', function() { return w; } + function addTrack(thisTrack, slices) { + var track = new TimelineSliceTrack(); + + track.heading = ''; + track.slices = slices; + track.viewport = thisTrack.viewport_; + + thisTrack.tracks_.push(track); + thisTrack.appendChild(track); + } + /** * Generic base class for timeline tracks */ @@ -96,19 +107,15 @@ cr.define('gpu', function() { this.textContent = ''; this.tracks_ = []; if (this.thread_) { + for (var srI = 0; srI < this.thread_.nonNestedSubRows.length; ++srI) { + addTrack(this, this.thread_.nonNestedSubRows[srI]); + } for (var srI = 0; srI < this.thread_.subRows.length; ++srI) { - var track = new TimelineSliceTrack(); - - if (srI == 0) - track.heading = this.thread_.parent.pid + ': ' + - this.thread_.tid + ': '; - else - track.heading = ''; - track.slices = this.thread_.subRows[srI]; - track.viewport = this.viewport_; - - this.tracks_.push(track); - this.appendChild(track); + addTrack(this, this.thread_.subRows[srI]); + } + if (this.tracks_.length > 0) { + this.tracks_[0].heading = this.thread_.parent.pid + ': ' + + this.thread_.tid + ': '; } } }, diff --git a/chrome/browser/resources/gpu_internals/tracing_controller_tests.js b/chrome/browser/resources/gpu_internals/tracing_controller_tests.js index 000f89b..a331b9b 100644 --- a/chrome/browser/resources/gpu_internals/tracing_controller_tests.js +++ b/chrome/browser/resources/gpu_internals/tracing_controller_tests.js @@ -28,6 +28,22 @@ var allTracingControllerTestDataSets; {"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: "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':829,'ph':'B','name':'NonNest','args':{'id':'1','ui-nest':'0'}}, + {'cat':'PERF','pid':22630,'tid':22630,'ts':830,'ph':'B','name':'NonNest','args':{'id':'2','ui-nest':'0'}}, + {'cat':'PERF','pid':22630,'tid':22630,'ts':831,'ph':'E','name':'Asub','args':{}}, + {'cat':'PERF','pid':22630,'tid':22630,'ts':832,'ph':'E','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':22631,'ts':827,'ph':'B','name':'A','args':{}}, + {'cat':'PERF','pid':22630,'tid':22631,'ts':854,'ph':'E','name':'A','args':{}} + ] } ]; allTracingControllerTestDataSets = dataSets; |