blob: 9afb90626c41f4cbf9004426939da3e3457c99de [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2015 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="/perf_insights/timeline_based_measurement/rendering_frame.html">
<link rel="import" href="/tracing/base/range.html">
<link rel="import" href="/tracing/base/statistics.html">
<link rel="import" href="/tracing/core/test_utils.html">
<link rel="import" href="/tracing/extras/chrome/cc/constants.html">
<link rel="import" href="/tracing/extras/chrome/chrome_test_utils.html">
<link rel="import" href="/tracing/model/model.html">
<script>
'use strict';
tr.b.unittest.testSuite(function() {
var ThreadSlice = tr.model.ThreadSlice;
var RenderingFrame = pi.tbm.RenderingFrame;
var SEND_BEGIN_FRAME_EVENT = tr.e.cc.constants.SEND_BEGIN_FRAME_EVENT;
var BEGIN_MAIN_FRAME_EVENT = tr.e.cc.constants.BEGIN_MAIN_FRAME_EVENT;
var Range = tr.b.Range;
function RenderingFrameTestData() {
this.beginFrameId_ = 0;
this.events_ = [];
this.rendererProcess_ = (new tr.Model()).getOrCreateProcess(1);
this.mainThread_ = this.rendererProcess_.getOrCreateThread(11);
this.compositorThread_ = this.rendererProcess_.getOrCreateThread(12);
}
RenderingFrameTestData.prototype = {
get events() {
return this.events_;
},
get rendererProcess() {
return this.rendererProcess_;
},
get compositorThread() {
return this.compositorThread_;
},
addSendEvent: function(opt_ts, opt_duration) {
if (opt_ts === undefined)
opt_ts = 0;
if (opt_duration === undefined)
opt_duration = 1;
this.beginFrameId_ += 1;
var event = this.createEvent_(
SEND_BEGIN_FRAME_EVENT, opt_ts, opt_duration);
this.compositorThread_.sliceGroup.pushSlice(event);
},
addBeginMainFrameEvent: function(opt_ts, opt_duration) {
if (opt_ts === undefined)
opt_ts = 0;
if (opt_duration === undefined)
opt_duration = 1;
var event = this.createEvent_(
BEGIN_MAIN_FRAME_EVENT, opt_ts, opt_duration);
this.mainThread_.sliceGroup.pushSlice(event);
},
updateBounds: function() {
this.rendererProcess_.updateBounds();
},
createEvent_: function(eventTitle, ts, duration) {
var event = new ThreadSlice('cc,benchmark', eventTitle, 0, ts, {
'begin_frame_id': this.beginFrameId_
}, duration);
this.events_.push(event);
return event;
}
};
function generateTimelineRange(opt_start, opt_end) {
if (opt_start === undefined)
opt_start = 0;
if (opt_end === undefined)
opt_end = 100;
var timelineRange = new tr.b.Range();
timelineRange.min = opt_start;
timelineRange.max = opt_end;
return timelineRange;
}
test('renderingFrameConstruction', function() {
var r = new RenderingFrameTestData();
r.addSendEvent(10);
r.addBeginMainFrameEvent(20);
r.updateBounds();
var frames = RenderingFrame.getFrameEventsInsideRange(
r.rendererProcess, Range.fromExplicitRange(0, 30));
assert.equal(1, frames.length);
assert.equal(10, frames[0].queueDuration);
});
test('renderingFrame_missingSendBeginFrameEvents', function() {
var r = new RenderingFrameTestData();
r.addBeginMainFrameEvent(10);
r.updateBounds();
var frames = RenderingFrame.getFrameEventsInsideRange(
r.rendererProcess, Range.fromExplicitRange(0, 30));
assert.equal(0, frames.length);
});
test('renderingFrame_duplicateSendBeginFrameEvents', function() {
var r = new RenderingFrameTestData();
r.addSendEvent(10);
r.addBeginMainFrameEvent(20);
var begin_frame_id = r.events[0].args['begin_frame_id'];
r.compositorThread.sliceGroup.pushSlice(new ThreadSlice(
'cc,benchmark', SEND_BEGIN_FRAME_EVENT, 0, 30,
{'begin_frame_id': begin_frame_id}, 0));
r.updateBounds();
var frames = RenderingFrame.getFrameEventsInsideRange(
r.rendererProcess, Range.fromExplicitRange(0, 30));
assert.equal(0, frames.length);
});
test('renderingFrame_missingBeginMainFrameEvents', function() {
var r = new RenderingFrameTestData();
r.addSendEvent(10);
r.updateBounds();
var frames = RenderingFrame.getFrameEventsInsideRange(
r.rendererProcess, Range.fromExplicitRange(0, 30));
assert.equal(0, frames.length);
});
test('renderingFrame_duplicateBeginMainFrameEvents', function() {
var r = new RenderingFrameTestData();
r.addSendEvent(10);
r.addBeginMainFrameEvent(20);
r.addBeginMainFrameEvent(30);
r.addBeginMainFrameEvent(40);
r.updateBounds();
var frames = RenderingFrame.getFrameEventsInsideRange(
r.rendererProcess, Range.fromExplicitRange(0, 30));
assert.equal(1, frames.length);
assert.equal(30, frames[0].queueDuration);
});
test('renderingFrame_frameEventMissingBeginFrameId', function() {
var model = new tr.Model();
var process = model.getOrCreateProcess(1);
var main_thread = process.getOrCreateThread(11);
var model_range = {};
// Create an event without the begin_frame_id argument
var event = new ThreadSlice(
'cc,benchmark', BEGIN_MAIN_FRAME_EVENT, 0, 0.0);
main_thread.sliceGroup.pushSlice(event);
process.updateBounds();
try {
RenderingFrame.getFrameEventsInsideRange(process, model_range);
assert.isFalse(true, 'Exception should have been thrown');
} catch (err) {
assert.equal(true, true);
}
});
/**
* Test a basic sequenece, with expected frame queueing delays A and B.
*
* |----A----| |--B--|
* Main: [1] [1] [2]
*
* Compositor: [1] [2]
**/
test('renderingFrame_getFrameEventsInsideRange', function() {
var r = new RenderingFrameTestData();
r.addSendEvent(10);
r.addBeginMainFrameEvent(20);
r.addBeginMainFrameEvent(30);
r.addSendEvent(40);
r.addBeginMainFrameEvent(50);
r.updateBounds();
var timelineRange = generateTimelineRange();
var frameEvents = RenderingFrame.getFrameEventsInsideRange(
r.rendererProcess, timelineRange);
assert.equal(2, frameEvents.length);
assert.equal(20, frameEvents[0].queueDuration);
assert.equal(10, frameEvents[1].queueDuration);
});
/**
* Test a sequenece missing an initial SendBeginFrame.
*
* Only one frame should be returned, with expected frame queueing delay A.
* |--A--|
* Main: [0] [0] [2]
*
* Compositor: [2]
**/
test('renderingFrame_frameEventsMissingDataNotIncluded', function() {
var r = new RenderingFrameTestData();
r.addBeginMainFrameEvent(20);
r.addBeginMainFrameEvent(30);
r.addSendEvent(40);
r.addBeginMainFrameEvent(50);
r.updateBounds();
var timelineRange = generateTimelineRange();
var frameEvents = RenderingFrame.getFrameEventsInsideRange(
r.rendererProcess, timelineRange);
assert.equal(1, frameEvents.length);
assert.equal(10, frameEvents[0].queueDuration);
});
});
</script>