blob: dbfa70ace0afc00e98ae92257ca4649852a1c543 [file] [log] [blame]
//
// To use this script, the HTML has to have only one element and this element's className
// should be equal to "Benchmark".
//
// This script forces rendering the HTML element many times by changing its position and its
// size. The size can be very big to test the case of displaying only a small portion of the
// element and measure how fast the display will be in this case.
//
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype = {
scale : function(other) {
return new Point(this.x * other.x, this.y * other.y);
},
add : function(other) {
return new Point(this.x + other.x, this.y + other.y);
},
subtract : function(other) {
return new Point(this.x - other.x, this.y - other.y);
},
isAlmostEqual : function(other, threshold) {
return Math.abs(this.x - other.x) < threshold && Math.abs(this.y - other.y) < threshold;
}
}
function Rectangle(position, size) {
this.position = position;
this.size = size;
}
Rectangle.prototype = {
left : function() {
return this.position.x;
},
top : function() {
return this.position.y;
},
width : function() {
return this.size.x;
},
height : function() {
return this.size.y;
},
isAlmostEqual : function(other, threshold) {
return this.position.isAlmostEqual(other.position, threshold) && this.size.isAlmostEqual(other.size, threshold);
}
}
function ElapsedTime() {
this._startTime = PerfTestRunner.now();
this._stopTime = this._startTime;
}
ElapsedTime.prototype = {
start : function() {
this._startTime = this._stopTime = PerfTestRunner.now();
},
stop : function() {
this._stopTime = PerfTestRunner.now();
},
isActive : function() {
return this._startTime == this._stopTime;
},
elapsed : function() {
return (this.isActive() ? PerfTestRunner.now() : this._stopTime) - this._startTime;
},
elapsedString : function() {
var tenths = this.elapsed() / 1000;
return tenths.toFixed(2) + " Seconds";
}
}
function AnimateMove(offset, zoomFactor, animateFactor) {
this.offset = offset;
this.zoomFactor = zoomFactor;
this.animateFactor = animateFactor;
}
AnimateMove.centerFactor = new Point(0.5, 0.5);
AnimateMove.prototype = {
targetRect : function(windowSize, sourceSize) {
var offset = this.offset.scale(this.zoomFactor);
var size = sourceSize.scale(this.zoomFactor);
var position = windowSize.subtract(size).scale(AnimateMove.centerFactor).subtract(offset);
return new Rectangle(position, size);
},
nextAnimateRect : function(targetRect, animateRect) {
var deltaPosition = targetRect.position.subtract(animateRect.position).scale(this.animateFactor);
var deltaSize = targetRect.size.subtract(animateRect.size).scale(this.animateFactor);
return new Rectangle(animateRect.position.add(deltaPosition), animateRect.size.add(deltaSize));
}
}
function ElementAnimator(element, windowSize, sourceSize) {
this._element = element;
this._windowSize = windowSize;
this._sourceSize = sourceSize;
this._animateMoves = [
new AnimateMove(new Point( 0, 0), new Point( 0.7, 0.7), new Point(1.00, 1.00)),
new AnimateMove(new Point(-500, -300), new Point(12.0, 12.0), new Point(0.50, 0.50)),
new AnimateMove(new Point( 100, -200), new Point( 0.1, 0.1), new Point(0.50, 0.50)),
new AnimateMove(new Point(-100, -300), new Point( 5.0, 5.0), new Point(0.20, 0.20)),
new AnimateMove(new Point( 0, 0), new Point( 0.7, 0.7), new Point(0.50, 0.50))
];
this._animateMoveIndex = 0;
this.nextTargetRect();
this._animateRect = this._targetRect;
this.moveToAnimateRect();
}
ElementAnimator.prototype = {
nextTargetRect : function() {
if (this._animateMoveIndex >= this._animateMoves.length)
return false;
this._targetRect = this._animateMoves[this._animateMoveIndex++].targetRect(this._windowSize, this._sourceSize);
return true;
},
nextAnimateRect : function() {
if (this._animateRect.isAlmostEqual(this._targetRect, 0.1))
return false;
this._animateRect = this._animateMoves[this._animateMoveIndex - 1].nextAnimateRect(this._targetRect, this._animateRect);
return true;
},
moveToAnimateRect : function() {
this._element.style.width = this._animateRect.width() + "px";
this._element.style.left = this._animateRect.left() + "px";
this._element.style.top = this._animateRect.top() + "px";
}
}
function RenderAnimator() {
this.element = document.getElementsByClassName("Benchmark")[0];
this.sourceSize = new Point(this.element.width, this.element.height);
// Tiling causes the rendering to slow down when the window width > 2000
this.windowSize = new Point(3000, 1500);
this.timer = document.createElement("span");
this.timer.className = "Timer";
document.body.appendChild(this.timer);
this.timeoutDelay = window.testRunner ? 0 : 500;
this.elapsedTime = new ElapsedTime();
this.elementAnimator = null;
}
RenderAnimator.prototype = {
nextRun : function() {
this.showElements(true);
this.elementAnimator = new ElementAnimator(this.element, this.windowSize, this.sourceSize);
var self = this;
setTimeout(function () {
self.elapsedTime.start();
self.moveToNextTargetRect();
}, this.timeoutDelay);
},
moveToNextTargetRect : function() {
if (this.elementAnimator.nextTargetRect())
setTimeout(this.moveToNextAnimateRect.bind(this), 0);
else {
this.elapsedTime.stop();
setTimeout(this.finishRun.bind(this), this.timeoutDelay);
}
},
moveToNextAnimateRect : function() {
this.timer.innerHTML = this.elapsedTime.elapsedString();
if (this.elementAnimator.nextAnimateRect())
window.requestAnimationFrame(this.moveToNextAnimateRect.bind(this));
else
this.moveToNextTargetRect();
this.elementAnimator.moveToAnimateRect();
},
finishRun : function() {
this.showElements(false);
var finishedTest = !PerfTestRunner.measureValueAsync(this.elapsedTime.elapsed());
PerfTestRunner.gc();
if (!finishedTest)
setTimeout(this.nextRun.bind(this), this.timeoutDelay * 2);
},
showElements : function(show) {
this.element.style.visibility = "visible";
this.element.style.opacity = show ? 1 : 0;
this.timer.style.opacity = show ? 1 : 0;
},
removeElements : function() {
this.element.parentNode.removeChild(this.element);
this.timer.parentNode.removeChild(this.timer);
this.element = null;
this.timer = null;
}
}
window.addEventListener("load", function() {
window.renderAnimator = new RenderAnimator();
window.renderAnimator.nextRun();
});
PerfTestRunner.prepareToMeasureValuesAsync({
unit: 'ms',
done: function () {
window.renderAnimator.removeElements();
}
});