| <!DOCTYPE html> |
| <!-- |
| Copyright 2017 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. |
| --> |
| |
| <link rel="import" href="/tracing/base/math/range.html"> |
| <link rel="import" href="/tracing/base/math/sorted_array_utils.html"> |
| <link rel="import" href="/tracing/base/unit_scale.html"> |
| <link rel="import" href="/tracing/model/event_container.html"> |
| <link rel="import" href="/tracing/model/resource_usage_sample.html"> |
| |
| <script> |
| 'use strict'; |
| |
| tr.exportTo('tr.model', function() { |
| var ResourceUsageSample = tr.model.ResourceUsageSample; |
| |
| /** |
| * A container holding a time series of samples giving the |
| * fraction of usage of a resource (e.g. CPU or GPU) at each |
| * sample time. |
| */ |
| |
| class ResourceUsageSeries extends tr.model.EventContainer { |
| constructor(device) { |
| super(); |
| |
| this.device_ = device; |
| this.samples_ = []; |
| } |
| |
| get device() { |
| return this.device_; |
| } |
| |
| get samples() { |
| return this.samples_; |
| } |
| |
| get stableId() { |
| return this.device_.stableId + '.ResourceUsageSeries'; |
| } |
| |
| /** |
| * Adds a usage sample to the series and returns it. |
| * |
| * Note: Samples must be added in chronological order. |
| */ |
| addUsageSample(ts, val) { |
| var sample = new ResourceUsageSample(this, ts, val); |
| this.samples_.push(sample); |
| return sample; |
| } |
| |
| /** |
| * Returns the total time consumed by a resource (e.g. CPU or GPU) between |
| * the specified start and end timestamps (in milliseconds). |
| */ |
| computeResourceTimeConsumedInMs(start, end) { |
| var measurementRange = tr.b.math.Range.fromExplicitRange(start, end); |
| |
| var resourceTimeInMs = 0; |
| var startIndex = tr.b.math.findLowIndexInSortedArray( |
| this.samples, x => x.start, start) - 1; |
| var endIndex = tr.b.math.findLowIndexInSortedArray( |
| this.samples, x => x.start, end); |
| |
| if (startIndex < 0) startIndex = 0; |
| |
| for (var i = startIndex; i < endIndex; i++) { |
| var sample = this.samples[i]; |
| var nextSample = this.samples[i + 1]; |
| |
| var sampleRange = new tr.b.math.Range(); |
| sampleRange.addValue(sample.start); |
| sampleRange.addValue(nextSample ? nextSample.start : sample.start); |
| |
| var intersectionRangeInMs = measurementRange.findIntersection( |
| sampleRange); |
| |
| resourceTimeInMs += intersectionRangeInMs.duration * sample.usage; |
| } |
| |
| return resourceTimeInMs; |
| } |
| |
| getSamplesWithinRange(start, end) { |
| var startIndex = tr.b.math.findLowIndexInSortedArray( |
| this.samples, x => x.start, start); |
| var endIndex = tr.b.math.findLowIndexInSortedArray( |
| this.samples, x => x.start, end); |
| return this.samples.slice(startIndex, endIndex); |
| } |
| |
| shiftTimestampsForward(amount) { |
| for (var i = 0; i < this.samples_.length; ++i) |
| this.samples_[i].start += amount; |
| } |
| |
| updateBounds() { |
| this.bounds.reset(); |
| |
| if (this.samples_.length === 0) return; |
| |
| this.bounds.addValue(this.samples_[0].start); |
| this.bounds.addValue(this.samples_[this.samples_.length - 1].start); |
| } |
| |
| * childEvents() { |
| yield* this.samples_; |
| } |
| } |
| |
| return { |
| ResourceUsageSeries, |
| }; |
| }); |
| </script> |