Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2509)

Unified Diff: chrome/browser/resources/gpu_internals/timeline_model.js

Issue 7555005: Moving the contents of chrome://gpu Profiling to chrome://tracing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/gpu_internals/timeline_model.js
diff --git a/chrome/browser/resources/gpu_internals/timeline_model.js b/chrome/browser/resources/gpu_internals/timeline_model.js
deleted file mode 100644
index a92d6ac3f0b1a0c081fcc4809632d2a04e02b453..0000000000000000000000000000000000000000
--- a/chrome/browser/resources/gpu_internals/timeline_model.js
+++ /dev/null
@@ -1,419 +0,0 @@
-// Copyright (c) 2011 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.
-
-
-/**
- * @fileoverview TimelineModel is a parsed representation of the
- * TraceEvents obtained from base/trace_event in which the begin-end
- * tokens are converted into a hierarchy of processes, threads,
- * subrows, and slices.
- *
- * The building block of the model is a slice. A slice is roughly
- * equivalent to function call executing on a specific thread. As a
- * result, slices may have one or more subslices.
- *
- * A thread contains one or more subrows of slices. Row 0 corresponds to
- * the "root" slices, e.g. the topmost slices. Row 1 contains slices that
- * are nested 1 deep in the stack, and so on. We use these subrows to draw
- * nesting tasks.
- *
- */
-cr.define('gpu', function() {
- /**
- * A TimelineSlice represents an interval of time on a given thread
- * associated with a specific trace event. For example,
- * TRACE_EVENT_BEGIN1("x","myArg", 7) at time=0.1ms
- * TRACE_EVENT_END() at time=0.3ms
- * Results in a single timeline slice from 0.1 with duration 0.2.
- *
- * All time units are stored in milliseconds.
- * @constructor
- */
- function TimelineSlice(title, colorId, start, args) {
- this.title = title;
- this.start = start;
- this.colorId = colorId;
- this.args = args;
- this.didNotFinish = false;
- this.subSlices = [];
- }
-
- TimelineSlice.prototype = {
- selected: false,
-
- duration: undefined,
-
- get end() {
- return this.start + this.duration;
- }
- };
-
- /**
- * 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. There
- * is also a set of non-nested subrows.
- *
- * @constructor
- */
- function TimelineThread(parent, tid) {
- this.parent = parent;
- this.tid = tid;
- this.subRows = [[]];
- this.nonNestedSubRows = [];
- }
-
- TimelineThread.prototype = {
- /**
- * Name of the thread, if present.
- */
- name: undefined,
-
- getSubrow: function(i) {
- while (i >= this.subRows.length)
- this.subRows.push([]);
- 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]);
- },
-
- /**
- * Updates the minTimestamp and maxTimestamp fields based on the
- * current slices and nonNestedSubRows attached to the thread.
- */
- updateBounds: function() {
- 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;
- }
- }
-
- };
-
- /**
- * 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.
- * @constructor
- */
- function TimelineProcess(pid) {
- this.pid = pid;
- this.threads = {};
- };
-
- TimelineProcess.prototype = {
- getThread: function(tid) {
- if (!this.threads[tid])
- this.threads[tid] = new TimelineThread(this, tid);
- return this.threads[tid];
- }
- };
-
- /**
- * Builds a model from an array of TraceEvent objects.
- * @param {Array} events An array of TraceEvents created by
- * TraceEvent.ToJSON().
- * @constructor
- */
- function TimelineModel(events) {
- this.processes = {};
- this.importErrors = [];
-
- if (events)
- this.importEvents(events);
- }
-
- TimelineModel.prototype = {
- __proto__: cr.EventTarget.prototype,
-
- getProcess: function(pid) {
- if (!this.processes[pid])
- this.processes[pid] = new TimelineProcess(pid);
- return this.processes[pid];
- },
-
- /**
- * The import takes an array of json-ified TraceEvents and adds them into
- * the TimelineModel as processes, threads, and slices.
- */
- 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;
- function ThreadState(tid) {
- this.openSlices = [];
- this.openNonNestedSlices = {};
- }
- var threadStateByPTID = {};
-
- var nameToColorMap = {};
- function getColor(name) {
- if (!(name in nameToColorMap)) {
- // Compute a simplistic hashcode of the string so we get consistent
- // coloring across traces.
- var hash = 0;
- for (var i = 0; i < name.length; ++i)
- hash = (hash + 37 * hash + 11 * name.charCodeAt(i)) % 0xFFFFFFFF;
- nameToColorMap[name] = hash % numColorIds;
- }
- return nameToColorMap[name];
- }
-
- var self = this;
-
- /**
- * Helper to process a 'begin' event (e.g. initiate a slice).
- * @param {ThreadState} state Thread state (holds slices).
- * @param {Object} event The current trace event.
- */
- function processBegin(state, event) {
- var colorId = getColor(event.name);
- var slice =
- { index: eI,
- slice: new TimelineSlice(event.name, colorId, event.ts,
- event.args) };
- if (event.args['ui-nest'] === '0') {
- var sliceID = event.name;
- for (var x in event.args)
- sliceID += ';' + event.args[x];
- if (state.openNonNestedSlices[sliceID])
- this.importErrors.push('Event ' + sliceID + ' already open.');
- state.openNonNestedSlices[sliceID] = slice;
- } else {
- state.openSlices.push(slice);
- }
- }
-
- /**
- * Helper to process an 'end' event (e.g. close a slice).
- * @param {ThreadState} state Thread state (holds slices).
- * @param {Object} event The current trace event.
- */
- function processEnd(state, event) {
- 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)
- return;
- slice.slice.duration = event.ts - slice.slice.start;
-
- // Store the slice in a non-nested subrow.
- var thread = self.getProcess(event.pid).getThread(event.tid);
- thread.addNonNestedSlice(slice.slice);
- delete state.openNonNestedSlices[name];
- } else {
- if (state.openSlices.length == 0) {
- // Ignore E events that are unmatched.
- return;
- }
- var slice = state.openSlices.pop().slice;
- slice.duration = event.ts - slice.start;
-
- // Store the slice on the correct subrow.
- var thread = self.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.slice.subSlices.push(slice);
- }
- }
- }
-
- // Walk through events
- for (var eI = 0; eI < events.length; eI++) {
- var event = events[eI];
- var ptid = event.pid + ':' + event.tid;
-
- if (!(ptid in threadStateByPTID))
- threadStateByPTID[ptid] = new ThreadState();
- var state = threadStateByPTID[ptid];
-
- if (event.ph == 'B') {
- processBegin(state, event);
- } else if (event.ph == 'E') {
- processEnd(state, event);
- } else if (event.ph == 'I') {
- // Treat an Instant event as a duration 0 slice.
- // 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 {
- 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
- // are events that were still open when trace was ended, and can often
- // indicate deadlock behavior.
- for (var ptid in threadStateByPTID) {
- var state = threadStateByPTID[ptid];
- while (state.openSlices.length > 0) {
- var slice = state.openSlices.pop();
- slice.slice.duration = this.maxTimestamp - slice.slice.start;
- slice.slice.didNotFinish = true;
- var event = events[slice.index];
-
- // Store the slice on the correct subrow.
- var thread = this.getProcess(event.pid).getThread(event.tid);
- var subRowIndex = state.openSlices.length;
- thread.getSubrow(subRowIndex).push(slice.slice);
-
- // Add the slice to the subSlices array of its parent.
- if (state.openSlices.length) {
- var parentSlice = state.openSlices[state.openSlices.length - 1];
- parentSlice.slice.subSlices.push(slice.slice);
- }
- }
- }
-
- this.shiftWorldToMicroseconds();
-
- var boost = (this.maxTimestamp - this.minTimestamp) * 0.15;
- this.minTimestamp = this.minTimestamp - boost;
- 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;
- var threads = this.getAllThreads();
- for (var tI = 0; tI < threads.length; tI++) {
- var thread = threads[tI];
- thread.updateBounds();
- if (thread.minTimestamp != undefined &&
- thread.maxTimestamp != undefined) {
- wmin = Math.min(wmin, thread.minTimestamp);
- wmax = Math.max(wmax, thread.maxTimestamp);
- }
- }
- this.minTimestamp = wmin;
- this.maxTimestamp = wmax;
- },
-
- shiftWorldToMicroseconds: function() {
- var timeBase = this.minTimestamp;
- var threads = this.getAllThreads();
- for (var tI = 0; tI < threads.length; tI++) {
- var thread = threads[tI];
- 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]);
- }
- }
-
- this.updateBounds();
- },
-
- getAllThreads: function() {
- var threads = [];
- for (var pid in this.processes) {
- var process = this.processes[pid];
- for (var tid in process.threads) {
- threads.push(process.threads[tid]);
- }
- }
- return threads;
- }
-
- };
-
- return {
- TimelineSlice: TimelineSlice,
- TimelineThread: TimelineThread,
- TimelineProcess: TimelineProcess,
- TimelineModel: TimelineModel
- };
-});
« no previous file with comments | « chrome/browser/resources/gpu_internals/timeline.js ('k') | chrome/browser/resources/gpu_internals/timeline_track.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698