testsCount: null,
progressBar: null,
- didRunTest: function ()
+ initialize: function(suites, options)
{
- this.progressBar.incRange();
+ this.testsCount = this.iterationCount * suites.reduce(function (count, suite) { return count + suite.tests.length; }, 0);
+ this.options = options;
},
-
+
willStartFirstIteration: function ()
{
this.results = new ResultsDashboard();
this.progressBar = new ProgressBar(document.getElementById("progress-completed"), this.testsCount);
+ },
+
+ didRunTest: function()
+ {
+ this.progressBar.incrementRange();
}
});
return formElement.checked;
return formElement.value;
},
-
+
updateUIFromLocalStorage: function()
{
var formElements = document.forms["benchmark-options"].elements;
updateLocalStorageFromUI: function()
{
var formElements = document.forms["benchmark-options"].elements;
- var options = {};
+ var options = {};
for (var i = 0; i < formElements.length; ++i) {
var formElement = formElements[i];
options[name] = formElement.checked;
else if (type == "radio")
options[name] = formElements[name].value;
-
+
localStorage.setItem(name, options[name]);
}
-
+
return options;
}
}
{
return document.querySelector("#suites > .tree");
},
-
+
_suitesElements: function()
{
return document.querySelectorAll("#suites > ul > li");
},
-
+
_checkboxElement: function(element)
{
return element.querySelector("input[type='checkbox']:not(.expand-button)");
{
return document.querySelectorAll("#suites input[type='number']");
},
-
+
_localStorageNameForTest: function(suiteName, testName)
{
return suiteName + "/" + testName;
{
var suitesElements = this._suitesElements();
var startButton = document.querySelector("#intro button");
-
+
for (var i = 0; i < suitesElements.length; ++i) {
var suiteElement = suitesElements[i];
var suiteCheckbox = this._checkboxElement(suiteElement);
-
+
if (suiteCheckbox.checked) {
startButton.disabled = false;
return;
}
}
-
+
startButton.disabled = true;
},
var selected = event.target.checked;
event.target.testsElements.forEach(function(testElement) {
var testCheckbox = this._checkboxElement(testElement);
- testCheckbox.checked = selected;
+ testCheckbox.checked = selected;
}, this);
this._updateStartButtonState();
},
}, this);
}, this);
},
-
+
updateEditsElementsState: function()
{
var editsElements = this._editsElements();
updateUIFromLocalStorage: function()
{
var suitesElements = this._suitesElements();
-
+
for (var i = 0; i < suitesElements.length; ++i) {
var suiteElement = suitesElements[i];
var suiteCheckbox = this._checkboxElement(suiteElement);
var suite = suiteCheckbox.suite;
-
+
suiteCheckbox.testsElements.forEach(function(testElement) {
var testCheckbox = this._checkboxElement(testElement);
var testEdit = this._editElement(testElement);
var test = testCheckbox.test;
-
+
var str = localStorage.getItem(this._localStorageNameForTest(suite.name, test.name));
if (str === null)
return;
this._updateSuiteCheckboxState(suiteCheckbox);
}
-
+
this._updateStartButtonState();
},
{
var suitesElements = this._suitesElements();
var suites = [];
-
+
for (var i = 0; i < suitesElements.length; ++i) {
var suiteElement = suitesElements[i];
var suiteCheckbox = this._checkboxElement(suiteElement);
var testCheckbox = this._checkboxElement(testElement);
var testEdit = this._editElement(testElement);
var test = testCheckbox.test;
-
+
if (testCheckbox.checked) {
test.complexity = testEdit.value;
tests.push(test);
}
- var value = { checked: testCheckbox.checked, complexity: testEdit.value };
+ var value = { checked: testCheckbox.checked, complexity: testEdit.value };
localStorage.setItem(this._localStorageNameForTest(suite.name, test.name), JSON.stringify(value));
}, this);
return suites;
},
-
+
updateLocalStorageFromJSON: function(iterationResults)
{
for (var suiteName in iterationResults[Strings.json.results.suites]) {
this.next();
}
-BenchmarkRunnerState.prototype.currentSuite = function()
-{
- return this._suites[this._suiteIndex];
-};
-
-BenchmarkRunnerState.prototype.currentTest = function()
-{
- var suite = this.currentSuite();
- return suite ? suite.tests[this._testIndex] : null;
-};
-
-BenchmarkRunnerState.prototype.isFirstTest = function()
-{
- return !this._testIndex;
-};
-
-BenchmarkRunnerState.prototype.next = function()
-{
- this._testIndex++;
-
- var suite = this._suites[this._suiteIndex];
- if (suite && this._testIndex < suite.tests.length)
- return this;
-
- this._testIndex = 0;
- do {
- this._suiteIndex++;
- } while (this._suiteIndex < this._suites.length && this._suites[this._suiteIndex].disabled);
+BenchmarkRunnerState.prototype = {
+ currentSuite: function()
+ {
+ return this._suites[this._suiteIndex];
+ },
+
+ currentTest: function()
+ {
+ var suite = this.currentSuite();
+ return suite ? suite.tests[this._testIndex] : null;
+ },
+
+ isFirstTest: function()
+ {
+ return !this._testIndex;
+ },
+
+ next: function()
+ {
+ this._testIndex++;
+
+ var suite = this._suites[this._suiteIndex];
+ if (suite && this._testIndex < suite.tests.length)
+ return;
+
+ this._testIndex = 0;
+ do {
+ this._suiteIndex++;
+ } while (this._suiteIndex < this._suites.length && this._suites[this._suiteIndex].disabled);
+ },
+
+ prepareCurrentTest: function(runner, frame)
+ {
+ var test = this.currentTest();
+ var promise = new SimplePromise;
- return this;
-};
+ frame.onload = function() {
+ promise.resolve();
+ };
-BenchmarkRunnerState.prototype.prepareCurrentTest = function(runner, frame)
-{
- var suite = this.currentSuite();
- var test = this.currentTest();
- var promise = new SimplePromise;
- frame.onload = function() {
- suite.prepare(runner, frame.contentWindow, frame.contentDocument).then(function(result) { promise.resolve(result); });
+ frame.src = "tests/" + test.url;
+ return promise;
}
- frame.src = "tests/" + test.url;
- return promise;
};
function BenchmarkRunner(suites, frameContainer, client)
this._frameContainer = frameContainer;
}
-BenchmarkRunner.prototype.waitForElement = function(selector)
-{
- var promise = new SimplePromise;
- var contentDocument = this._frame.contentDocument;
-
- function resolveIfReady() {
- var element = contentDocument.querySelector(selector);
- if (element)
- return promise.resolve(element);
- setTimeout(resolveIfReady, 50);
- }
+BenchmarkRunner.prototype = {
+ _appendFrame: function()
+ {
+ var frame = document.createElement("iframe");
+ frame.setAttribute("scrolling", "no");
+
+ this._frameContainer.insertBefore(frame, this._frameContainer.firstChild);
+ this._frame = frame;
+ return frame;
+ },
+
+ _removeFrame: function()
+ {
+ if (this._frame) {
+ this._frame.parentNode.removeChild(this._frame);
+ this._frame = null;
+ }
+ },
+
+ _runBenchmarkAndRecordResults: function(state)
+ {
+ var promise = new SimplePromise;
+ var suite = state.currentSuite();
+ var test = state.currentTest();
- resolveIfReady();
- return promise;
-};
+ if (this._client && this._client.willRunTest)
+ this._client.willRunTest(suite, test);
-BenchmarkRunner.prototype._appendFrame = function()
-{
- var frame = document.createElement("iframe");
- frame.setAttribute("scrolling", "no");
+ var contentWindow = this._frame.contentWindow;
+ var self = this;
- this._frameContainer.insertBefore(frame, this._frameContainer.firstChild);
- this._frame = frame;
- return frame;
-};
+ var options = { complexity: test.complexity };
+ Utilities.extendObject(options, this._client.options);
+ Utilities.extendObject(options, contentWindow.Utilities.parseParameters());
-BenchmarkRunner.prototype._removeFrame = function()
-{
- if (this._frame) {
- this._frame.parentNode.removeChild(this._frame);
- this._frame = null;
- }
-};
+ var benchmark = new contentWindow.benchmarkClass(options);
+ benchmark.run().then(function(sampler) {
+ var samplers = self._suitesSamplers[suite.name] || {};
+ samplers[test.name] = sampler.toJSON(true, true);
+ self._suitesSamplers[suite.name] = samplers;
-BenchmarkRunner.prototype._runTestAndRecordResults = function(state)
-{
- var promise = new SimplePromise;
- var suite = state.currentSuite();
- var test = state.currentTest();
-
- if (this._client && this._client.willRunTest)
- this._client.willRunTest(suite, test);
-
- var contentWindow = this._frame.contentWindow;
- var self = this;
-
- suite.run(contentWindow, test, this._client.options, this._client.progressBar).then(function(sampler) {
- var samplers = self._suitesSamplers[suite.name] || {};
- samplers[test.name] = sampler.toJSON(true, true);
- self._suitesSamplers[suite.name] = samplers;
-
- if (self._client && self._client.didRunTest)
- self._client.didRunTest(suite, test);
-
- state.next();
- if (state.currentSuite() != suite)
- self._removeFrame();
- promise.resolve(state);
- });
-
- return promise;
-};
+ if (self._client && self._client.didRunTest)
+ self._client.didRunTest(suite, test);
-BenchmarkRunner.prototype.step = function(state)
-{
- if (!state) {
- state = new BenchmarkRunnerState(this._suites);
- this._suitesSamplers = {};
- }
+ state.next();
+ if (state.currentSuite() != suite)
+ self._removeFrame();
+ promise.resolve(state);
+ });
- var suite = state.currentSuite();
- if (!suite) {
- this._finalize();
- var promise = new SimplePromise;
- promise.resolve();
return promise;
+ },
+
+ step: function(state)
+ {
+ if (!state) {
+ state = new BenchmarkRunnerState(this._suites);
+ this._suitesSamplers = {};
+ }
+
+ var suite = state.currentSuite();
+ if (!suite) {
+ this._finalize();
+ var promise = new SimplePromise;
+ promise.resolve();
+ return promise;
+ }
+
+ if (state.isFirstTest()) {
+ this._appendFrame();
+ }
+
+ return state.prepareCurrentTest(this, this._frame).then(function(prepareReturnValue) {
+ return this._runBenchmarkAndRecordResults(state);
+ }.bind(this));
+ },
+
+ runAllSteps: function(startingState)
+ {
+ var nextCallee = this.runAllSteps.bind(this);
+ this.step(startingState).then(function(nextState) {
+ if (nextState)
+ nextCallee(nextState);
+ });
+ },
+
+ runMultipleIterations: function()
+ {
+ var self = this;
+ var currentIteration = 0;
+
+ this._runNextIteration = function() {
+ currentIteration++;
+ if (currentIteration < self._client.iterationCount)
+ self.runAllSteps();
+ else if (this._client && this._client.didFinishLastIteration)
+ self._client.didFinishLastIteration();
+ }
+
+ if (this._client && this._client.willStartFirstIteration)
+ this._client.willStartFirstIteration();
+
+ this.runAllSteps();
+ },
+
+ _finalize: function()
+ {
+ this._removeFrame();
+
+ if (this._client && this._client.didRunSuites)
+ this._client.didRunSuites(this._suitesSamplers);
+
+ if (this._runNextIteration)
+ this._runNextIteration();
}
-
- if (state.isFirstTest()) {
- this._appendFrame();
- }
-
- return state.prepareCurrentTest(this, this._frame).then(function(prepareReturnValue) {
- return this._runTestAndRecordResults(state);
- }.bind(this));
-};
-
-BenchmarkRunner.prototype.runAllSteps = function(startingState)
-{
- var nextCallee = this.runAllSteps.bind(this);
- this.step(startingState).then(function(nextState) {
- if (nextState)
- nextCallee(nextState);
- });
-};
-
-BenchmarkRunner.prototype.runMultipleIterations = function()
-{
- var self = this;
- var currentIteration = 0;
-
- this._runNextIteration = function() {
- currentIteration++;
- if (currentIteration < self._client.iterationCount)
- self.runAllSteps();
- else if (this._client && this._client.didFinishLastIteration)
- self._client.didFinishLastIteration();
- }
-
- if (self._client && self._client.willStartFirstIteration)
- self._client.willStartFirstIteration();
-
- self.runAllSteps();
-};
-
-BenchmarkRunner.prototype._finalize = function()
-{
- this._removeFrame();
-
- if (this._client && this._client.didRunSuites)
- this._client.didRunSuites(this._suitesSamplers);
-
- if (this._runNextIteration)
- this._runNextIteration();
};
Suites.push(new Suite("HTML suite",
[
- {
+ {
url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=12&particleHeight=12&shape=circle",
name: "CSS bouncing circles"
},
- {
+ {
url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=40&particleHeight=40&shape=rect&clip=star",
name: "CSS bouncing clipped rects"
},
- {
+ {
url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=50&particleHeight=50&shape=circle&fill=gradient",
name: "CSS bouncing gradient circles"
},
Suites.push(new Suite("Canvas suite",
[
- {
+ {
url: "bouncing-particles/bouncing-canvas-shapes.html?particleWidth=12&particleHeight=12&shape=circle",
name: "canvas bouncing circles"
},
- {
+ {
url: "bouncing-particles/bouncing-canvas-shapes.html?particleWidth=40&particleHeight=40&shape=rect&clip=star",
name: "canvas bouncing clipped rects"
},
- {
+ {
url: "bouncing-particles/bouncing-canvas-shapes.html?particleWidth=50&particleHeight=50&shape=circle&fill=gradient",
name: "canvas bouncing gradient circles"
},
- {
+ {
url: "bouncing-particles/bouncing-canvas-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.svg",
name: "canvas bouncing SVG images"
},
name: "Composited Transforms"
},
{
- url: "examples/canvas-electrons.html",
- name: "canvas electrons"
+ url: "misc/canvas-electrons.html",
+ name: "Canvas electrons"
},
{
- url: "examples/canvas-stars.html",
- name: "canvas stars"
+ url: "misc/canvas-stars.html",
+ name: "Canvas stars"
},
]
));
{
return this.x;
},
-
+
// Used when the point object is used as a size object.
get height()
{
return this.y;
},
-
+
// Used when the point object is used as a size object.
get center()
{
return new Point(this.x / 2, this.y / 2);
},
-
+
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);
},
-
+
multiply: function(other)
{
return new Point(this.x * other.x, this.y * other.y);
},
-
+
move: function(angle, velocity, timeDelta)
{
return this.add(Point.pointOnCircle(angle, velocity * (timeDelta / 1000)));
{
return this.top + this.bottom;
},
-
+
get size()
{
return new Point(this.width, this.height);
{
if (this._callback)
throw "SimplePromise doesn't support multiple calls to then";
-
+
this._callback = callback;
this._chainedPromise = new SimplePromise;
-
+
if (this._resolved)
this.resolve(this._resolvedValue);
const xlinkNamespace = "http://www.w3.org/1999/xlink";
var element = document.createElementNS(svgNamespace, name);
-
+
for (var key in attrs)
element.setAttribute(key, attrs[key]);
-
+
for (var key in xlinkAttrs)
element.setAttributeNS(xlinkNamespace, key, xlinkAttrs[key]);
-
+
parentElement.appendChild(element);
return element;
}
function ProgressBar(element, ranges)
{
- this.element = element;
- this.ranges = ranges;
- this.currentRange = 0;
+ this._element = element;
+ this._ranges = ranges;
+ this._currentRange = 0;
+ this._updateElement();
}
ProgressBar.prototype =
{
- _progressToPercent: function(progress)
- {
- return progress * (100 / this.ranges);
- },
-
- incRange: function()
+ _updateElement: function()
{
- ++this.currentRange;
+ this._element.style.width = (this._currentRange * (100 / this._ranges)) + "%";
},
-
- setPos: function(progress)
+
+ incrementRange: function()
{
- this.element.style.width = this._progressToPercent(this.currentRange + progress) + "%";
+ ++this._currentRange;
+ this._updateElement();
}
}
{
push: function(suitesSamplers)
{
- this._iterationsSamplers.push(suitesSamplers);
+ this._iterationsSamplers.push(suitesSamplers);
},
-
+
_processData: function(statistics, graph)
{
var iterationsResults = [];
var iterationsScores = [];
-
+
this._iterationsSamplers.forEach(function(iterationSamplers, index) {
var suitesResults = {};
var suitesScores = [];
-
+
for (var suiteName in iterationSamplers) {
var suite = suiteFromName(suiteName);
var suiteSamplerData = iterationSamplers[suiteName];
var testsResults = {};
var testsScores = [];
-
+
for (var testName in suiteSamplerData) {
testsResults[testName] = suiteSamplerData[testName];
testsScores.push(testsResults[testName][Strings.json.score]);
suitesResults[suiteName][Strings.json.results.tests] = testsResults;
suitesScores.push(suitesResults[suiteName][Strings.json.score]);
}
-
+
iterationsResults[index] = {};
iterationsResults[index][Strings.json.score] = Statistics.geometricMean(suitesScores);
iterationsResults[index][Strings.json.results.suites] = suitesResults;
var data = testResults[Strings.json.samples];
if (!data)
return;
-
+
var button = DocumentExtension.createElement("button", { class: "small-button" }, td);
button.addEventListener("click", function() {
complexity[Strings.json.measurements.concern].toFixed(2)].join("");
benchmarkController.showTestGraph(testName, score, mean, axes, samples, samplingTimeOffset);
});
-
+
button.textContent = Strings.text.results.graph + "...";
},
{
const percentThreshold = 10;
const averageThreshold = 2;
-
+
if (measurement == Strings.json.measurements.percent)
return data[Strings.json.measurements.percent] >= percentThreshold;
-
+
if (jsonExperiment == Strings.json.experiments.frameRate && measurement == Strings.json.measurements.average)
return Math.abs(data[Strings.json.measurements.average] - options["frame-rate"]) >= averageThreshold;
this._addTest(testName, testResults, options);
}
},
-
+
_addIteration: function(iterationResult, options)
{
for (var suiteName in iterationResult[Strings.json.results.suites]) {
{
this.clear();
this._addHeader();
-
+
iterationsResults.forEach(function(iterationResult) {
this._addIteration(iterationResult, options);
}, this);
mergeObjects: function(obj1, obj2)
{
return this.extendObject(this.copyObject(obj1), obj2);
+ },
+
+ createSubclass: function(superclass, classConstructor, extend)
+ {
+ classConstructor.prototype = Object.create(superclass.prototype);
+ classConstructor.prototype.constructor = classConstructor;
+ if (extend)
+ Utilities.extendObject(classConstructor.prototype, extend);
+ return classConstructor;
}
}
initialize: function(suites, options)
{
- this.testsCount = this.iterationCount * suites.reduce(function (count, suite) { return count + suite.tests.length; }, 0);
this.options = options;
},
this.name = name;
this.tests = tests;
};
-Suite.prototype.prepare = function(runner, contentWindow, contentDocument)
-{
- return runner.waitForElement("#stage").then(function (element) {
- return element;
- });
-};
-Suite.prototype.run = function(contentWindow, test, options, progressBar)
-{
- return contentWindow.runBenchmark(this, test, options, progressBar);
-};
var Suites = [];
score: "Score",
samples: "Samples",
- runningState: {
- warming: "Warming",
- sampling: "Sampling",
- finished: "Finished"
- },
-
experiments: {
complexity: "Complexity",
frameRate: "FPS"
},
-
+
measurements: {
average: "Avg.",
concern: "W.5%",
stdev: "Std.",
percent: "%"
},
-
+
results: {
results: "Results",
graph: "Graph",
json: {
score: "score",
samples: "samples",
-
+
experiments: {
complexity: "complexity",
frameRate: "frameRate"
},
-
+
measurements: {
average: "average",
concern: "concern",
stdev: "stdev",
percent: "percent"
},
-
+
results: {
iterations: "iterationsResults",
suites: "suitesResults",
tests: "testsResults"
},
-
+
graph: {
points: "points",
samplingTimeOffset: "samplingTimeOffset"
<!DOCTYPE html>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="../resources/stage.css">
<style>
img.hidden {
position: absolute;
visibility: hidden;
}
</style>
- <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <img class="hidden" src="../resources/yin-yang.svg">
+ <img class="hidden" src="../resources/yin-yang.png">
+ <canvas id="stage"></canvas>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/bouncing-particles.js"></script>
<script src="resources/bouncing-canvas-particles.js"></script>
<script src="resources/bouncing-canvas-images.js"></script>
-</head>
-<body>
- <img class="hidden" src="../resources/yin-yang.svg">
- <img class="hidden" src="../resources/yin-yang.png">
- <canvas id="stage"></canvas>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <canvas id="stage"></canvas>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/bouncing-particles.js"></script>
<script src="resources/bouncing-canvas-particles.js"></script>
<script src="resources/bouncing-canvas-shapes.js"></script>
-</head>
-<body>
- <canvas id="stage"></canvas>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="../resources/stage.css">
<style>
img {
position: absolute;
}
</style>
- <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <div id="stage"></div>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/bouncing-particles.js"></script>
<script src="resources/bouncing-css-images.js"></script>
-</head>
-<body>
- <div id="stage"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="../resources/stage.css">
<style>
.circle {
position: absolute;
}
.star {
-webkit-clip-path: polygon(50% 0%, 38% 38%, 0% 38%, 30% 60%, 18% 100%, 50% 75%, 82% 100%, 70% 60%, 100% 38%, 62% 38%);
- -ms-clip-path: polygon(50% 0%, 38% 38%, 0% 38%, 30% 60%, 18% 100%, 50% 75%, 82% 100%, 70% 60%, 100% 38%, 62% 38%);
+ -ms-clip-path: polygon(50% 0%, 38% 38%, 0% 38%, 30% 60%, 18% 100%, 50% 75%, 82% 100%, 70% 60%, 100% 38%, 62% 38%);
clip-path: polygon(50% 0%, 38% 38%, 0% 38%, 30% 60%, 18% 100%, 50% 75%, 82% 100%, 70% 60%, 100% 38%, 62% 38%);
}
</style>
- <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <div id="stage"></div>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/bouncing-particles.js"></script>
<script src="resources/bouncing-css-shapes.js"></script>
-</head>
-<body>
- <div id="stage"></div>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <svg id="stage"></svg>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/bouncing-particles.js"></script>
<script src="resources/bouncing-svg-particles.js"></script>
<script src="resources/bouncing-svg-images.js"></script>
-</head>
-<body>
- <svg id="stage"></svg>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <svg id="stage"></svg>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/bouncing-particles.js"></script>
<script src="resources/bouncing-svg-particles.js"></script>
<script src="resources/bouncing-svg-shapes.js"></script>
-</head>
-<body>
- <svg id="stage"></svg>
</body>
</html>
-function BouncingCanvasImage(stage)
-{
- BouncingCanvasParticle.call(this, stage);
- this._imageElement = stage.imageElement;
- this._shape = "image";
-}
-
-BouncingCanvasImage.prototype = Object.create(BouncingCanvasParticle.prototype);
-BouncingCanvasImage.prototype.constructor = BouncingCanvasImage;
-
-BouncingCanvasImage.prototype._draw = function()
-{
- this._context.save();
- this._applyRotation();
- this._context.drawImage(this._imageElement, 0, 0, this._size.x, this._size.y);
- this._context.restore();
-}
-
-function BouncingCanvasImagesStage(element, options)
-{
- BouncingCanvasParticlesStage.call(this, element, options);
-
- var imageSrc = options["imageSrc"] || "resources/yin-yang.svg";
- this.imageElement = document.querySelector(".hidden[src=\"" + imageSrc + "\"]");
-}
-
-BouncingCanvasImagesStage.prototype = Object.create(BouncingCanvasParticlesStage.prototype);
-BouncingCanvasImagesStage.prototype.constructor = BouncingCanvasImagesStage;
-
-BouncingCanvasImagesStage.prototype.createParticle = function()
-{
- return new BouncingCanvasImage(this);
-}
-
-function BouncingCanvasImagesBenchmark(suite, test, options, progressBar)
-{
- BouncingCanvasParticlesBenchmark.call(this, suite, test, options, progressBar);
-}
-
-BouncingCanvasImagesBenchmark.prototype = Object.create(BouncingCanvasParticlesBenchmark.prototype);
-BouncingCanvasImagesBenchmark.prototype.constructor = BouncingCanvasImagesBenchmark;
-
-BouncingCanvasImagesBenchmark.prototype.createStage = function(element)
-{
- return new BouncingCanvasImagesStage(element, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- return new BouncingCanvasImagesBenchmark(suite, test, options, progressBar);
-}
+(function() {
+
+BouncingCanvasImage = Utilities.createSubclass(BouncingCanvasParticle,
+ function(stage)
+ {
+ BouncingCanvasParticle.call(this, stage, "image");
+ this._imageElement = stage.imageElement;
+ }, {
+
+ _draw: function()
+ {
+ this.context.save();
+ this.applyRotation();
+ this.context.drawImage(this._imageElement, 0, 0, this.size.x, this.size.y);
+ this.context.restore();
+ }
+});
+
+BouncingCanvasImagesStage = Utilities.createSubclass(BouncingCanvasParticlesStage,
+ function()
+ {
+ BouncingCanvasParticlesStage.call(this);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ BouncingCanvasParticlesStage.prototype.initialize.call(this, benchmark);
+ var imageSrc = benchmark.options["imageSrc"] || "resources/yin-yang.svg";
+ this.imageElement = document.querySelector(".hidden[src=\"" + imageSrc + "\"]");
+ },
+
+ createParticle: function()
+ {
+ return new BouncingCanvasImage(this);
+ }
+});
+
+BouncingCanvasImagesBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new BouncingCanvasImagesStage(), options);
+ }
+);
+
+window.benchmarkClass = BouncingCanvasImagesBenchmark;
+
+})();
-function BouncingCanvasParticle(stage)
-{
- BouncingParticle.call(this, stage);
- this._context = stage.context;
- this._shape = "";
- this._clip = stage.clip;
-}
+BouncingCanvasParticle = Utilities.createSubclass(BouncingParticle,
+ function(stage, shape)
+ {
+ BouncingParticle.call(this, stage);
+ this.context = stage.context;
+ this._shape = shape;
+ this._clip = stage.clip;
+ }, {
+
+ applyRotation: function()
+ {
+ if (this._shape == "circle")
+ return;
+
+ this.context.translate(this.size.x / 2, this.size.y / 2);
+ this.context.rotate(this.rotater.degree() * Math.PI / 180);
+ this.context.translate(-this.size.x / 2, -this.size.y / 2);
+ },
+
+ applyClipping: function()
+ {
+ var clipPoints = BouncingCanvasParticle.clips[this._clip];
+ if (!clipPoints)
+ return;
+
+ this.context.beginPath();
+ clipPoints.forEach(function(point, index) {
+ var point = this.size.multiply(point);
+ if (!index)
+ this.context.moveTo(point.x, point.y);
+ else
+ this.context.lineTo(point.x, point.y);
+ }, this);
+
+ this.context.closePath();
+ this.context.clip();
+ },
+
+ _draw: function()
+ {
+ throw "Not implemented";
+ },
+
+ animate: function(timeDelta)
+ {
+ BouncingParticle.prototype.animate.call(this, timeDelta);
+ this.context.save();
+ this.context.translate(this.position.x, this.position.y);
+ this._draw();
+ this.context.restore();
+ }
+});
BouncingCanvasParticle.clips = {
star: [
new Point(0.70, 0.60),
new Point(1.00, 0.38),
new Point(0.62, 0.38)
- ],
+ ]
};
-BouncingCanvasParticle.prototype = Object.create(BouncingParticle.prototype);
-BouncingCanvasParticle.prototype.constructor = BouncingCanvasParticle;
-
-BouncingCanvasParticle.prototype._applyRotation = function()
-{
- if (this._shape == "circle")
- return;
-
- this._context.translate(this._size.x / 2, this._size.y / 2);
- this._context.rotate(this._rotater.degree() * Math.PI / 180);
- this._context.translate(-this._size.x / 2, -this._size.y / 2);
-}
-
-BouncingCanvasParticle.prototype._applyClipping = function()
-{
- var clipPoints = BouncingCanvasParticle.clips[this._clip];
- if (!clipPoints)
- return;
-
- this._context.beginPath();
- clipPoints.forEach(function(point, index) {
- var point = this._size.multiply(point);
- if (!index)
- this._context.moveTo(point.x, point.y);
- else
- this._context.lineTo(point.x, point.y);
- }, this);
-
- this._context.closePath();
- this._context.clip();
-}
-
-BouncingCanvasParticle.prototype._draw = function()
-{
- throw "Not implemented";
-}
-
-BouncingCanvasParticle.prototype.animate = function(timeDelta)
-{
- BouncingParticle.prototype.animate.call(this, timeDelta);
- this._context.save();
- this._context.translate(this._position.x, this._position.y);
- this._draw();
- this._context.restore();
-}
-
-function BouncingCanvasParticlesStage(element, options)
-{
- BouncingParticlesStage.call(this, element, options);
- this.context = this.element.getContext("2d");
-}
-
-BouncingCanvasParticlesStage.prototype = Object.create(BouncingParticlesStage.prototype);
-BouncingCanvasParticlesStage.prototype.constructor = BouncingCanvasParticlesStage;
-
-function BouncingCanvasParticlesAnimator(benchmark, options)
-{
- BouncingParticlesAnimator.call(this, benchmark, options);
- this._context = benchmark._stage.context;
-}
-
-BouncingCanvasParticlesAnimator.prototype = Object.create(BouncingParticlesAnimator.prototype);
-BouncingCanvasParticlesAnimator.prototype.constructor = BouncingCanvasParticlesAnimator;
-
-BouncingCanvasParticlesAnimator.prototype.animate = function()
-{
- this._context.clearRect(0, 0, this._benchmark._stage.size.x, this._benchmark._stage.size.y);
- return BouncingParticlesAnimator.prototype.animate.call(this);
-}
-
-function BouncingCanvasParticlesBenchmark(suite, test, options, progressBar)
-{
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
-
-BouncingCanvasParticlesBenchmark.prototype = Object.create(StageBenchmark.prototype);
-BouncingCanvasParticlesBenchmark.prototype.constructor = BouncingCanvasParticlesBenchmark;
-
-BouncingCanvasParticlesBenchmark.prototype.createAnimator = function()
-{
- return new BouncingCanvasParticlesAnimator(this, this._options);
-}
\ No newline at end of file
+BouncingCanvasParticlesStage = Utilities.createSubclass(BouncingParticlesStage,
+ function()
+ {
+ BouncingParticlesStage.call(this);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ BouncingParticlesStage.prototype.initialize.call(this, benchmark);
+ this.context = this.element.getContext("2d");
+ },
+
+ animate: function(timeDelta)
+ {
+ this.context.clearRect(0, 0, this.size.x, this.size.y);
+ this.particles.forEach(function(particle) {
+ particle.animate(timeDelta);
+ });
+ }
+});
-function BouncingCanvasShape(stage)
-{
- BouncingCanvasParticle.call(this, stage);
- this._fill = stage.fill;
- this._shape = stage.shape;
- this._color0 = stage.randomColor();
- this._color1 = stage.randomColor();
-}
+(function() {
-BouncingCanvasShape.prototype = Object.create(BouncingCanvasParticle.prototype);
-BouncingCanvasShape.prototype.constructor = BouncingCanvasShape;
+BouncingCanvasShape = Utilities.createSubclass(BouncingCanvasParticle,
+ function(stage)
+ {
+ BouncingCanvasParticle.call(this, stage, stage.shape);
+ this._fill = stage.fill;
+ this._color0 = stage.randomColor();
+ this._color1 = stage.randomColor();
+ }, {
-BouncingCanvasShape.prototype._applyFill = function()
-{
- switch (this._fill) {
- case "gradient":
- var gradient = this._context.createLinearGradient(0, 0, this._size.width, 0);
- gradient.addColorStop(0, this._color0);
- gradient.addColorStop(1, this._color1);
- this._context.fillStyle = gradient;
- break;
-
- case "solid":
- default:
- this._context.fillStyle = this._color0;
- break;
- }
-}
+ _applyFill: function()
+ {
+ switch (this._fill) {
+ case "gradient":
+ var gradient = this.context.createLinearGradient(0, 0, this.size.width, 0);
+ gradient.addColorStop(0, this._color0);
+ gradient.addColorStop(1, this._color1);
+ this.context.fillStyle = gradient;
+ break;
-BouncingCanvasShape.prototype._drawShape = function()
-{
- this._context.beginPath();
+ case "solid":
+ default:
+ this.context.fillStyle = this._color0;
+ break;
+ }
+ },
- switch (this._shape) {
- case "rect":
- this._context.rect(0, 0, this._size.width, this._size.height);
- break;
-
- case "circle":
- default:
- var center = this._size.center;
- var radius = Math.min(this._size.x, this._size.y) / 2;
- this._context.arc(center.x, center.y, radius, 0, Math.PI * 2, true);
- break;
- }
+ _drawShape: function()
+ {
+ this.context.beginPath();
+
+ switch (this._shape) {
+ case "rect":
+ this.context.rect(0, 0, this.size.width, this.size.height);
+ break;
- this._context.fill();
-}
+ case "circle":
+ default:
+ var center = this.size.center;
+ var radius = Math.min(this.size.x, this.size.y) / 2;
+ this.context.arc(center.x, center.y, radius, 0, Math.PI * 2, true);
+ break;
+ }
-BouncingCanvasShape.prototype._draw = function()
-{
- this._context.save();
- this._applyFill();
- this._applyRotation();
- this._applyClipping();
- this._drawShape();
- this._context.restore();
-}
+ this.context.fill();
+ },
-function BouncingCanvasShapesStage(element, options)
-{
- BouncingCanvasParticlesStage.call(this, element, options);
- this.parseShapeParamters(options);
-}
+ _draw: function()
+ {
+ this.context.save();
+ this._applyFill();
+ this.applyRotation();
+ this.applyClipping();
+ this._drawShape();
+ this.context.restore();
+ }
+});
-BouncingCanvasShapesStage.prototype = Object.create(BouncingCanvasParticlesStage.prototype);
-BouncingCanvasShapesStage.prototype.constructor = BouncingCanvasShapesStage;
+BouncingCanvasShapesStage = Utilities.createSubclass(BouncingCanvasParticlesStage,
+ function ()
+ {
+ BouncingCanvasParticlesStage.call(this);
+ }, {
-BouncingCanvasShapesStage.prototype.createParticle = function()
-{
- return new BouncingCanvasShape(this);
-}
+ initialize: function(benchmark)
+ {
+ BouncingCanvasParticlesStage.prototype.initialize.call(this, benchmark);
+ this.parseShapeParameters(benchmark.options);
+ },
-function BouncingCanvasShapesBenchmark(suite, test, options, progressBar)
-{
- BouncingCanvasParticlesBenchmark.call(this, suite, test, options, progressBar);
-}
+ createParticle: function()
+ {
+ return new BouncingCanvasShape(this);
+ }
+});
-BouncingCanvasShapesBenchmark.prototype = Object.create(BouncingCanvasParticlesBenchmark.prototype);
-BouncingCanvasShapesBenchmark.prototype.constructor = BouncingCanvasShapesBenchmark;
+BouncingCanvasShapesBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new BouncingCanvasShapesStage(), options);
+ }
+);
-BouncingCanvasShapesBenchmark.prototype.createStage = function(element)
-{
- return new BouncingCanvasShapesStage(element, this._options);
-}
+window.benchmarkClass = BouncingCanvasShapesBenchmark;
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- return new BouncingCanvasShapesBenchmark(suite, test, options, progressBar);
-}
+})();
\ No newline at end of file
-function BouncingCssImage(stage)
-{
- BouncingParticle.call(this, stage);
-
- this.element = document.createElement("img");
- this.element.style.width = this._size.x + "px";
- this.element.style.height = this._size.y + "px";
- this.element.setAttribute("src", stage.imageSrc);
-
- stage.element.appendChild(this.element);
- this._move();
-}
-
-BouncingCssImage.prototype = Object.create(BouncingParticle.prototype);
-BouncingCssImage.prototype.constructor = BouncingCssImage;
-
-BouncingCssImage.prototype._move = function()
-{
- this.element.style.transform = "translate(" + this._position.x + "px," + this._position.y + "px) " + this._rotater.rotateZ();
-}
-
-BouncingCssImage.prototype.animate = function(timeDelta)
-{
- BouncingParticle.prototype.animate.call(this, timeDelta);
- this._move();
-}
-
-function BouncingCssImagesStage(element, options)
-{
- BouncingParticlesStage.call(this, element, options);
- this.imageSrc = options["imageSrc"] || "../resources/yin-yang.svg";
-}
-
-BouncingCssImagesStage.prototype = Object.create(BouncingParticlesStage.prototype);
-BouncingCssImagesStage.prototype.constructor = BouncingCssImagesStage;
-
-BouncingCssImagesStage.prototype.createParticle = function()
-{
- return new BouncingCssImage(this);
-}
-
-BouncingCssImagesStage.prototype.particleWillBeRemoved = function(particle)
-{
- particle.element.remove();
-}
-
-function BouncingCssImagesBenchmark(suite, test, options, progressBar)
-{
- BouncingParticlesBenchmark.call(this, suite, test, options, progressBar);
-}
-
-BouncingCssImagesBenchmark.prototype = Object.create(BouncingParticlesBenchmark.prototype);
-BouncingCssImagesBenchmark.prototype.constructor = BouncingCssImagesBenchmark;
-
-BouncingCssImagesBenchmark.prototype.createStage = function(element)
-{
- return new BouncingCssImagesStage(element, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- return new BouncingCssImagesBenchmark(suite, test, options, progressBar);
-}
+(function() {
+
+BouncingCssImage = Utilities.createSubclass(BouncingParticle,
+ function(stage)
+ {
+ BouncingParticle.call(this, stage);
+
+ this.element = document.createElement("img");
+ this.element.style.width = this.size.x + "px";
+ this.element.style.height = this.size.y + "px";
+ this.element.setAttribute("src", stage.imageSrc);
+
+ stage.element.appendChild(this.element);
+ this._move();
+ }, {
+
+ _move: function()
+ {
+ this.element.style.transform = "translate(" + this.position.x + "px," + this.position.y + "px) " + this.rotater.rotateZ();
+ },
+
+ animate: function(timeDelta)
+ {
+ BouncingParticle.prototype.animate.call(this, timeDelta);
+ this._move();
+ }
+});
+
+BouncingCssImagesStage = Utilities.createSubclass(BouncingParticlesStage,
+ function()
+ {
+ BouncingParticlesStage.call(this);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ BouncingParticlesStage.prototype.initialize.call(this, benchmark);
+ this.imageSrc = benchmark.options["imageSrc"] || "../resources/yin-yang.svg";
+ },
+
+ createParticle: function()
+ {
+ return new BouncingCssImage(this);
+ },
+
+ particleWillBeRemoved: function(particle)
+ {
+ particle.element.remove();
+ }
+});
+
+BouncingCssImagesBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new BouncingCssImagesStage(), options);
+ }
+);
+
+window.benchmarkClass = BouncingCssImagesBenchmark;
+
+})();
-function BouncingCssShape(stage)
-{
- BouncingParticle.call(this, stage);
+(function() {
- this.element = this._createSpan(stage);
-
- switch (stage.fill) {
- case "solid":
- default:
- this.element.style.backgroundColor = stage.randomColor();
- break;
-
- case "gradient":
- this.element.style.background = "linear-gradient(" + stage.randomColor() + ", " + stage.randomColor() + ")";
- break;
- }
+BouncingCssShape = Utilities.createSubclass(BouncingParticle,
+ function(stage)
+ {
+ BouncingParticle.call(this, stage);
+
+ this.element = this._createSpan(stage);
+
+ switch (stage.fill) {
+ case "solid":
+ default:
+ this.element.style.backgroundColor = stage.randomColor();
+ break;
- this._move();
-}
+ case "gradient":
+ this.element.style.background = "linear-gradient(" + stage.randomColor() + ", " + stage.randomColor() + ")";
+ break;
+ }
-BouncingCssShape.prototype = Object.create(BouncingParticle.prototype);
-BouncingCssShape.prototype.constructor = BouncingCssShape;
+ this._move();
+ }, {
-BouncingCssShape.prototype._createSpan = function(stage)
-{
- var span = document.createElement("span");
- span.className = stage.shape + " " + stage.clip;
- span.style.width = this._size.x + "px";
- span.style.height = this._size.y + "px";
- stage.element.appendChild(span);
- return span;
-}
+ _createSpan: function(stage)
+ {
+ var span = document.createElement("span");
+ span.className = stage.shape + " " + stage.clip;
+ span.style.width = this.size.x + "px";
+ span.style.height = this.size.y + "px";
+ stage.element.appendChild(span);
+ return span;
+ },
-BouncingCssShape.prototype._move = function()
-{
- this.element.style.transform = "translate(" + this._position.x + "px," + this._position.y + "px)" + this._rotater.rotateZ();
-}
-
-BouncingCssShape.prototype.animate = function(timeDelta)
-{
- BouncingParticle.prototype.animate.call(this, timeDelta);
- this._rotater.next(timeDelta);
- this._move();
-}
+ _move: function()
+ {
+ this.element.style.transform = "translate(" + this.position.x + "px," + this.position.y + "px)" + this.rotater.rotateZ();
+ },
-function BouncingCssShapesStage(element, options)
-{
- BouncingParticlesStage.call(this, element, options);
- this.parseShapeParamters(options);
-}
+ animate: function(timeDelta)
+ {
+ BouncingParticle.prototype.animate.call(this, timeDelta);
+ this.rotater.next(timeDelta);
+ this._move();
+ }
+});
-BouncingCssShapesStage.prototype = Object.create(BouncingParticlesStage.prototype);
-BouncingCssShapesStage.prototype.constructor = BouncingCssShapesStage;
+BouncingCssShapesStage = Utilities.createSubclass(BouncingParticlesStage,
+ function()
+ {
+ BouncingParticlesStage.call(this);
+ }, {
-BouncingCssShapesStage.prototype.createParticle = function()
-{
- return new BouncingCssShape(this);
-}
+ initialize: function(benchmark)
+ {
+ BouncingParticlesStage.prototype.initialize.call(this, benchmark);
+ this.parseShapeParameters(benchmark.options);
+ },
-BouncingCssShapesStage.prototype.particleWillBeRemoved = function(particle)
-{
- particle.element.remove();
-}
+ createParticle: function()
+ {
+ return new BouncingCssShape(this);
+ },
-function BouncingCssShapesBenchmark(suite, test, options, progressBar)
-{
- BouncingParticlesBenchmark.call(this, suite, test, options, progressBar);
-}
+ particleWillBeRemoved: function(particle)
+ {
+ particle.element.remove();
+ }
+});
-BouncingCssShapesBenchmark.prototype = Object.create(BouncingParticlesBenchmark.prototype);
-BouncingCssShapesBenchmark.prototype.constructor = BouncingCssShapesBenchmark;
+BouncingCssShapesBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new BouncingCssShapesStage(), options);
+ }
+);
-BouncingCssShapesBenchmark.prototype.createStage = function(element)
-{
- return new BouncingCssShapesStage(element, this._options);
-}
+window.benchmarkClass = BouncingCssShapesBenchmark;
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- return new BouncingCssShapesBenchmark(suite, test, options, progressBar);
-}
+})();
function BouncingParticle(stage)
{
this._stageSize = stage.size;
- this._size = stage.particleSize;
-
- this._position = stage.randomPosition(stage.size.subtract(stage.particleSize));
+ this.size = stage.particleSize;
+
+ this.position = stage.randomPosition(stage.size.subtract(stage.particleSize));
this._angle = stage.randomAngle();
this._velocity = stage.randomVelocity(stage.maxVelocity);
- this._rotater = stage.randomRotater();
+ this.rotater = stage.randomRotater();
}
BouncingParticle.prototype =
{
get center()
{
- return this._position.add(this._size.center);
+ return this.position.add(this.size.center);
},
-
+
animate: function(timeDelta)
{
- this._position = this._position.move(this._angle, this._velocity, timeDelta);
- this._rotater.next(timeDelta);
+ this.position = this.position.move(this._angle, this._velocity, timeDelta);
+ this.rotater.next(timeDelta);
// If particle is going to move off right side
- if (this._position.x + this._size.x > this._stageSize.x) {
+ if (this.position.x + this.size.x > this._stageSize.x) {
// If direction is East-South, go West-South.
if (this._angle >= 0 && this._angle < Math.PI / 2)
this._angle = Math.PI - this._angle;
else if (this._angle > Math.PI / 2 * 3)
this._angle = this._angle - (this._angle - Math.PI / 2 * 3) * 2;
// Make sure the particle does not go outside the stage boundaries.
- this._position.x = this._stageSize.x - this._size.x;
+ this.position.x = this._stageSize.x - this.size.x;
}
-
+
// If particle is going to move off left side
- if (this._position.x < 0) {
+ if (this.position.x < 0) {
// If angle is West-South, go East-South.
if (this._angle > Math.PI / 2 && this._angle < Math.PI)
this._angle = Math.PI - this._angle;
else if (this._angle > Math.PI && this._angle < Math.PI / 2 * 3)
this._angle = this._angle + (Math.PI / 2 * 3 - this._angle) * 2;
// Make sure the particle does not go outside the stage boundaries.
- this._position.x = 0;
+ this.position.x = 0;
}
// If particle is going to move off bottom side
- if (this._position.y + this._size.y > this._stageSize.y) {
+ if (this.position.y + this.size.y > this._stageSize.y) {
// If direction is South, go North.
if (this._angle > 0 && this._angle < Math.PI)
this._angle = Math.PI * 2 - this._angle;
// Make sure the particle does not go outside the stage boundaries.
- this._position.y = this._stageSize.y - this._size.y;
+ this.position.y = this._stageSize.y - this.size.y;
}
// If particle is going to move off top side
- if (this._position.y < 0) {
+ if (this.position.y < 0) {
// If direction is North, go South.
if (this._angle > Math.PI && this._angle < Math.PI * 2)
this._angle = this._angle - (this._angle - Math.PI) * 2;
// Make sure the particle does not go outside the stage boundaries.
- this._position.y = 0;
+ this.position.y = 0;
}
}
}
-function BouncingParticlesAnimator(benchmark, options)
-{
- StageAnimator.call(this, benchmark, options);
-};
-
-BouncingParticlesAnimator.prototype = Object.create(StageAnimator.prototype);
-BouncingParticlesAnimator.prototype.constructor = BouncingParticlesAnimator;
-
-function BouncingParticlesStage(element, options)
-{
- Stage.call(this, element, options);
-
- this.particleSize = new Point(parseInt(options["particleWidth"]) || 10, parseInt(options["particleHeight"]) || 10);
- this._particles = [];
-
- this.maxVelocity = parseInt(options["maxVelocity"]) || 500;
- this.maxVelocity = Math.max(this.maxVelocity, 100);
-}
+BouncingParticlesStage = Utilities.createSubclass(Stage,
+ function()
+ {
+ Stage.call(this);
+ this.particles = [];
+ }, {
-BouncingParticlesStage.prototype = Object.create(Stage.prototype);
-BouncingParticlesStage.prototype.constructor = BouncingParticlesStage;
+ initialize: function(benchmark)
+ {
+ Stage.prototype.initialize.call(this, benchmark);
+ this.particleSize = new Point(parseInt(benchmark.options["particleWidth"]) || 10, parseInt(benchmark.options["particleHeight"]) || 10);
+ this.maxVelocity = Math.max(parseInt(benchmark.options["maxVelocity"]) || 500, 100);
+ },
-BouncingParticlesStage.prototype.parseShapeParamters = function(options)
-{
- this.shape = options["shape"] || "circle";
- this.fill = options["fill"] || "solid";
- this.clip = options["clip"] || "";
-}
+ parseShapeParameters: function(options)
+ {
+ this.shape = options["shape"] || "circle";
+ this.fill = options["fill"] || "solid";
+ this.clip = options["clip"] || "";
+ },
-BouncingParticlesStage.prototype.animate = function(timeDelta)
-{
- this._particles.forEach(function(particle) {
- particle.animate(timeDelta);
- });
-}
-
-BouncingParticlesStage.prototype.tune = function(count)
-{
- if (count == 0)
- return this._particles.length;
-
- if (count > 0) {
- console.assert(typeof(this.createParticle) == "function");
- for (var i = 0; i < count; ++i)
- this._particles.push(this.createParticle());
- return this._particles.length;
- }
+ animate: function(timeDelta)
+ {
+ this.particles.forEach(function(particle) {
+ particle.animate(timeDelta);
+ });
+ },
- count = Math.min(-count, this._particles.length);
-
- if (typeof(this.particleWillBeRemoved) == "function") {
- for (var i = 0; i < count; ++i)
- this.particleWillBeRemoved(this._particles[this._particles.length - 1 - i]);
- }
+ tune: function(count)
+ {
+ if (count == 0)
+ return this.particles.length;
- this._particles.splice(-count, count);
- return this._particles.length;
-}
+ if (count > 0) {
+ for (var i = 0; i < count; ++i)
+ this.particles.push(this.createParticle());
+ return this.particles.length;
+ }
-function BouncingParticlesBenchmark(suite, test, options, progressBar)
-{
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
+ count = Math.min(-count, this.particles.length);
-BouncingParticlesBenchmark.prototype = Object.create(StageBenchmark.prototype);
-BouncingParticlesBenchmark.prototype.constructor = BouncingParticlesBenchmark;
+ if (typeof(this.particleWillBeRemoved) == "function") {
+ for (var i = 0; i < count; ++i)
+ this.particleWillBeRemoved(this.particles[this.particles.length - 1 - i]);
+ }
-BouncingParticlesBenchmark.prototype.createAnimator = function()
-{
- return new BouncingParticlesAnimator(this, this._options);
-}
\ No newline at end of file
+ this.particles.splice(-count, count);
+ return this.particles.length;
+ }
+});
-function BouncingSvgImage(stage)
-{
- BouncingSvgParticle.call(this, stage);
- this._shape = "image";
-
- var attrs = { x: 0, y: 0, width: this._size.x, height: this._size.y };
- var xlinkAttrs = { href: stage.imageSrc };
- this.element = DocumentExtension.createSvgElement("image", attrs, xlinkAttrs, stage.element);
- this._move();
-}
-
-BouncingSvgImage.prototype = Object.create(BouncingSvgParticle.prototype);
-BouncingSvgImage.prototype.constructor = BouncingSvgImage;
-
-function BouncingSvgImagesStage(element, options)
-{
- BouncingParticlesStage.call(this, element, options);
- this.imageSrc = options["imageSrc"] || "resources/yin-yang.svg";
-}
-
-BouncingSvgImagesStage.prototype = Object.create(BouncingSvgParticlesStage.prototype);
-BouncingSvgImagesStage.prototype.constructor = BouncingSvgImagesStage;
-
-BouncingSvgImagesStage.prototype.createParticle = function()
-{
- return new BouncingSvgImage(this);
-}
-
-function BouncingSvgImagesBenchmark(suite, test, options, progressBar)
-{
- BouncingParticlesBenchmark.call(this, suite, test, options, progressBar);
-}
-
-BouncingSvgImagesBenchmark.prototype = Object.create(BouncingParticlesBenchmark.prototype);
-BouncingSvgImagesBenchmark.prototype.constructor = BouncingSvgImagesBenchmark;
-
-BouncingSvgImagesBenchmark.prototype.createStage = function(element)
-{
- return new BouncingSvgImagesStage(element, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- return new BouncingSvgImagesBenchmark(suite, test, options, progressBar);
-}
+(function() {
+
+BouncingSvgImage = Utilities.createSubclass(BouncingSvgParticle,
+ function(stage)
+ {
+ BouncingSvgParticle.call(this, stage, "image");
+
+ var attrs = { x: 0, y: 0, width: this.size.x, height: this.size.y };
+ var xlinkAttrs = { href: stage.imageSrc };
+ this.element = DocumentExtension.createSvgElement("image", attrs, xlinkAttrs, stage.element);
+ this._move();
+ }
+);
+
+BouncingSvgImagesStage = Utilities.createSubclass(BouncingSvgParticlesStage,
+ function()
+ {
+ BouncingSvgParticlesStage.call(this);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ BouncingSvgParticlesStage.prototype.initialize.call(this, benchmark);
+ this.imageSrc = benchmark.options["imageSrc"] || "resources/yin-yang.svg";
+ },
+
+ createParticle: function()
+ {
+ return new BouncingSvgImage(this);
+ }
+});
+
+BouncingSvgImagesBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new BouncingSvgImagesStage(), options);
+ }
+);
+
+window.benchmarkClass = BouncingSvgImagesBenchmark;
+
+})();
+
-function BouncingSvgParticle(stage)
-{
- BouncingParticle.call(this, stage);
-}
+BouncingSvgParticle = Utilities.createSubclass(BouncingParticle,
+ function(stage, shape)
+ {
+ BouncingParticle.call(this, stage);
+ this._shape = shape;
+ }, {
-BouncingSvgParticle.prototype = Object.create(BouncingParticle.prototype);
-BouncingSvgParticle.prototype.constructor = BouncingParticle;
+ _applyClipping: function(stage)
+ {
+ if (stage.clip != "star")
+ return;
-BouncingSvgParticle.prototype._applyClipping = function(stage)
-{
- if (stage.clip != "star")
- return;
-
- stage.ensureClipStarIsCreated();
- this.element.setAttribute("clip-path", "url(#star-clip)");
-}
+ stage.ensureClipStarIsCreated();
+ this.element.setAttribute("clip-path", "url(#star-clip)");
+ },
-BouncingSvgParticle.prototype._move = function()
-{
- var transform = "translate(" + this._position.x + ", " + this._position.y + ")";
- if (this._shape != "circle")
- transform += this._rotater.rotate(this._size.center);
- this.element.setAttribute("transform", transform);
-}
+ _move: function()
+ {
+ var transform = "translate(" + this.position.x + ", " + this.position.y + ")";
+ if (this._shape != "circle")
+ transform += this.rotater.rotate(this.size.center);
+ this.element.setAttribute("transform", transform);
+ },
-BouncingSvgParticle.prototype.animate = function(timeDelta)
-{
- BouncingParticle.prototype.animate.call(this, timeDelta);
- this._move();
-}
+ animate: function(timeDelta)
+ {
+ BouncingParticle.prototype.animate.call(this, timeDelta);
+ this._move();
+ }
+});
-function BouncingSvgParticlesStage(element, options)
-{
- BouncingParticlesStage.call(this, element, options);
-}
+BouncingSvgParticlesStage = Utilities.createSubclass(BouncingParticlesStage,
+ function()
+ {
+ BouncingParticlesStage.call(this);
+ }, {
-BouncingSvgParticlesStage.prototype = Object.create(BouncingParticlesStage.prototype);
-BouncingSvgParticlesStage.prototype.constructor = BouncingSvgParticlesStage;
+ _createDefs: function()
+ {
+ return DocumentExtension.createSvgElement("defs", {}, {}, this.element);
+ },
-BouncingSvgParticlesStage.prototype._createDefs = function()
-{
- return DocumentExtension.createSvgElement("defs", {}, {}, this.element);
-}
-
-BouncingSvgParticlesStage.prototype._ensureDefsIsCreated = function()
-{
- return this.element.querySelector("defs") || this._createDefs();
-}
+ _ensureDefsIsCreated: function()
+ {
+ return this.element.querySelector("defs") || this._createDefs();
+ },
-BouncingSvgParticlesStage.prototype._createClipStar = function()
-{
- var attrs = { id: "star-clip", clipPathUnits: "objectBoundingBox" };
- var clipPath = DocumentExtension.createSvgElement("clipPath", attrs, {}, this._ensureDefsIsCreated());
+ _createClipStar: function()
+ {
+ var attrs = { id: "star-clip", clipPathUnits: "objectBoundingBox" };
+ var clipPath = DocumentExtension.createSvgElement("clipPath", attrs, {}, this._ensureDefsIsCreated());
- attrs = { d: "M.50,0L.38,.38L0,.38L.30,.60L.18,1L.50,.75L.82,1L.70,.60L1,.38L.62,.38z" };
- DocumentExtension.createSvgElement("path", attrs, {}, clipPath);
- return clipPath;
-}
+ attrs = { d: "M.50,0L.38,.38L0,.38L.30,.60L.18,1L.50,.75L.82,1L.70,.60L1,.38L.62,.38z" };
+ DocumentExtension.createSvgElement("path", attrs, {}, clipPath);
+ return clipPath;
+ },
-BouncingSvgParticlesStage.prototype.ensureClipStarIsCreated = function()
-{
- return this.element.querySelector("#star-clip") || this._createClipStar();
-}
+ ensureClipStarIsCreated: function()
+ {
+ return this.element.querySelector("#star-clip") || this._createClipStar();
+ },
-BouncingSvgParticlesStage.prototype.particleWillBeRemoved = function(particle)
-{
- particle.element.remove();
-}
+ particleWillBeRemoved: function(particle)
+ {
+ particle.element.remove();
+ }
+});
-function BouncingSvgShape(stage)
-{
- BouncingSvgParticle.call(this, stage);
- this._shape = stage.shape;
- this._fill = stage.fill;
-
- this._createShape(stage);
- this._applyClipping(stage);
- this._applyFill(stage);
-
- this._move();
-}
-
-BouncingSvgShape.prototype = Object.create(BouncingSvgParticle.prototype);
-BouncingSvgShape.prototype.constructor = BouncingSvgShape;
-
-BouncingSvgShape.prototype._createShape = function(stage)
-{
- switch (this._shape) {
- case "rect":
- var attrs = { x: 0, y: 0, width: this._size.x, height: this._size.y };
- this.element = DocumentExtension.createSvgElement("rect", attrs, {}, stage.element);
- break;
-
- case "circle":
- default:
- var attrs = { cx: this._size.x / 2, cy: this._size.y / 2, r: Math.min(this._size.x, this._size.y) / 2 };
- this.element = DocumentExtension.createSvgElement("circle", attrs, {}, stage.element);
- break;
+(function() {
+
+BouncingSvgShape = Utilities.createSubclass(BouncingSvgParticle,
+ function(stage)
+ {
+ BouncingSvgParticle.call(this, stage, stage.shape);
+ this._fill = stage.fill;
+
+ this._createShape(stage);
+ this._applyClipping(stage);
+ this._applyFill(stage);
+
+ this._move();
+ }, {
+
+ _createShape: function(stage)
+ {
+ switch (this._shape) {
+ case "rect":
+ var attrs = { x: 0, y: 0, width: this.size.x, height: this.size.y };
+ this.element = DocumentExtension.createSvgElement("rect", attrs, {}, stage.element);
+ break;
+
+ case "circle":
+ default:
+ var attrs = { cx: this.size.x / 2, cy: this.size.y / 2, r: Math.min(this.size.x, this.size.y) / 2 };
+ this.element = DocumentExtension.createSvgElement("circle", attrs, {}, stage.element);
+ break;
+ }
+ },
+
+ _applyFill: function(stage)
+ {
+ switch (this._fill) {
+ case "gradient":
+ var gradient = stage.createGradient(2);
+ this.element.setAttribute("fill", "url(#" + gradient.getAttribute("id") + ")");
+ break;
+
+ case "solid":
+ default:
+ this.element.setAttribute("fill", stage.randomColor());
+ break;
+ }
}
-}
-
-BouncingSvgShape.prototype._applyFill = function(stage)
-{
- switch (this._fill) {
- case "gradient":
- var gradient = stage.createGradient(2);
- this.element.setAttribute("fill", "url(#" + gradient.getAttribute("id") + ")");
- break;
-
- case "solid":
- default:
- this.element.setAttribute("fill", stage.randomColor());
- break;
+});
+
+BouncingSvgShapesStage = Utilities.createSubclass(BouncingSvgParticlesStage,
+ function()
+ {
+ BouncingSvgParticlesStage.call(this);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ BouncingSvgParticlesStage.prototype.initialize.call(this, benchmark);
+ this.parseShapeParameters(benchmark.options);
+ this._gradientsCount = 0;
+ },
+
+ createGradient: function(stops)
+ {
+ var attrs = { id: "gradient-" + ++this._gradientsCount };
+ var gradient = DocumentExtension.createSvgElement("linearGradient", attrs, {}, this._ensureDefsIsCreated());
+
+ for (var i = 0; i < stops; ++i) {
+ attrs = { offset: i * 100 / stops + "%", 'stop-color': this.randomColor() };
+ DocumentExtension.createSvgElement("stop", attrs, {}, gradient);
+ }
+
+ return gradient;
+ },
+
+ createParticle: function()
+ {
+ return new BouncingSvgShape(this);
+ },
+
+ particleWillBeRemoved: function(particle)
+ {
+ BouncingSvgParticlesStage.prototype.particleWillBeRemoved.call(this, particle);
+
+ var fill = particle.element.getAttribute("fill");
+ if (fill.indexOf("url(#") != 0)
+ return;
+
+ var gradient = this.element.querySelector(fill.substring(4, fill.length - 1));
+ this._ensureDefsIsCreated().removeChild(gradient);
}
-}
-
-function BouncingSvgShapesStage(element, options)
-{
- BouncingSvgParticlesStage.call(this, element, options);
- this.parseShapeParamters(options);
- this._gradientsCount = 0;
-}
-
-BouncingSvgShapesStage.prototype = Object.create(BouncingSvgParticlesStage.prototype);
-BouncingSvgShapesStage.prototype.constructor = BouncingSvgShapesStage;
-
-BouncingSvgShapesStage.prototype.createGradient = function(stops)
-{
- var attrs = { id: "gadient-" + ++this._gradientsCount };
- var gradient = DocumentExtension.createSvgElement("linearGradient", attrs, {}, this._ensureDefsIsCreated());
-
- for (var i = 0; i < stops; ++i) {
- attrs = { offset: i * 100 / stops + "%", 'stop-color': this.randomColor() };
- DocumentExtension.createSvgElement("stop", attrs, {}, gradient);
+});
+
+BouncingSvgShapesBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new BouncingSvgShapesStage(), options);
}
+);
+
+window.benchmarkClass = BouncingSvgShapesBenchmark;
- return gradient;
-}
-
-BouncingSvgShapesStage.prototype.createParticle = function()
-{
- return new BouncingSvgShape(this);
-}
-
-BouncingSvgShapesStage.prototype.particleWillBeRemoved = function(particle)
-{
- BouncingSvgParticlesStage.prototype.particleWillBeRemoved.call(this, particle);
-
- var fill = particle.element.getAttribute("fill");
- if (fill.indexOf("url(#") != 0)
- return;
-
- var gradient = this.element.querySelector(fill.substring(4, fill.length - 1));
- this._ensureDefsIsCreated().removeChild(gradient);
-}
-
-function BouncingSvgShapesBenchmark(suite, test, options, progressBar)
-{
- BouncingParticlesBenchmark.call(this, suite, test, options, progressBar);
-}
-
-BouncingSvgShapesBenchmark.prototype = Object.create(BouncingParticlesBenchmark.prototype);
-BouncingSvgShapesBenchmark.prototype.constructor = BouncingSvgShapesBenchmark;
-
-BouncingSvgShapesBenchmark.prototype.createStage = function(element)
-{
- return new BouncingSvgShapesStage(element, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- return new BouncingSvgShapesBenchmark(suite, test, options, progressBar);
-}
+})();
+++ /dev/null
-function CanvasElectron(stage)
-{
- this._context = stage.context;
- this._stageSize = stage.size;
-
- var minSide = Math.min(this._stageSize.width, this._stageSize.height);
- var radiusX = stage.random(minSide / 8, 7 * minSide / 16);
- var radiusY = stage.random(minSide / 8, 3 * radiusX / 4);
- this._orbitRadiuses = new Point(radiusX, radiusY);
- this._radius = stage.random(5, 15);
- this._direction = stage.randomInt(0, 2);
- this._angle = stage.randomInt(0, 360);
- this._color = stage.randomColor();
- this._rotater = stage.randomRotater();
- this._rotater.next(stage.random(0, this._rotater.interval));
-}
-
-CanvasElectron.prototype._draw = function()
-{
- // Calculate the position of the object on the ellipse.
- var angle = this._direction ? this._rotater.degree() : 360 - this._rotater.degree();
- var position = this._stageSize.center.subtract(Point.pointOnEllipse(angle, this._orbitRadiuses));
-
- this._context.save();
- this._context.translate(this._stageSize.center.x, this._stageSize.center.y);
- this._context.rotate(this._angle * Math.PI / 180);
- this._context.translate(-this._stageSize.center.x, -this._stageSize.center.y);
-
- // Set the stroke and the fill colors
- this._context.strokeStyle = "rgba(192, 192, 192, 0.9)";
- this._context.fillStyle = this._color;
-
- // Draw the orbit of the object.
- this._context.beginPath();
- this._context.ellipse(this._stageSize.center.x, this._stageSize.center.y, this._orbitRadiuses.x, this._orbitRadiuses.y, 0, 0, 2 * Math.PI);
- this._context.stroke();
-
- // Draw the object.
- this._context.beginPath();
- this._context.arc(position.x, position.y, this._radius, 0, Math.PI * 2, true);
- this._context.fill();
- this._context.restore();
-}
-
-CanvasElectron.prototype.animate = function(timeDelta)
-{
- this._rotater.next(timeDelta / 100);
- this._draw();
-}
-
-function CanvasElectronsStage(element, options)
-{
- Stage.call(this, element, options);
- this.context = this.element.getContext("2d");
- this._electrons = [];
-}
-
-CanvasElectronsStage.prototype = Object.create(Stage.prototype);
-CanvasElectronsStage.prototype.constructor = CanvasElectronsStage;
-
-CanvasElectronsStage.prototype.tune = function(count)
-{
- if (count == 0)
- return this._electrons.length;
-
- if (count > 0) {
- for (var i = 0; i < count; ++i)
- this._electrons.push(new CanvasElectron(this));
- return this._electrons.length;
- }
-
- count = Math.min(-count, this._electrons.length);
- this._electrons.splice(-count, count);
-
- return this._electrons.length;
-}
-
-CanvasElectronsStage.prototype.animate = function(timeDelta)
-{
- this._electrons.forEach(function(electron) {
- electron.animate(timeDelta);
- });
-}
-
-function CanvasElectronsAnimator(benchmark, options)
-{
- Animator.call(this, benchmark, options);
- this._context = benchmark._stage.context;
-}
-
-CanvasElectronsAnimator.prototype = Object.create(StageAnimator.prototype);
-CanvasElectronsAnimator.prototype.constructor = CanvasElectronsAnimator;
-
-CanvasElectronsAnimator.prototype.animate = function()
-{
- this._context.clearRect(0, 0, this._benchmark._stage.size.x, this._benchmark._stage.size.y);
-
- // Draw a big star in the middle.
- this._context.fillStyle = "orange";
- this._context.beginPath();
- this._context.arc(this._benchmark._stage.size.center.x, this._benchmark._stage.size.center.y, 50, 0, Math.PI * 2, true);
- this._context.fill();
-
- return StageAnimator.prototype.animate.call(this);
-}
-
-function CanvasElectronsBenchmark(suite, test, options, progressBar)
-{
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
-
-CanvasElectronsBenchmark.prototype = Object.create(StageBenchmark.prototype);
-CanvasElectronsBenchmark.prototype.constructor = CanvasElectronsBenchmark;
-
-CanvasElectronsBenchmark.prototype.createStage = function(element)
-{
- // Attach the stage to the benchmark.
- return new CanvasElectronsStage(element, this._options);
-}
-
-CanvasElectronsBenchmark.prototype.createAnimator = function()
-{
- // Attach the animator to the benchmark.
- return new CanvasElectronsAnimator(this, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- // This function is called from the test harness which starts the
- // test by creating your benchmark object.
- return new CanvasElectronsBenchmark(suite, test, options, progressBar);
-}
+++ /dev/null
-function CanvasStar(stage)
-{
- this._context = stage.context;
- this._stageSize = stage.size;
-
- this._size = stage.randomSquareSize(5, 20);
- this._center = stage.randomPosition(stage.size.subtract(this._size)).add(this._size.center);
- this._rotateX = 0;
- this._rotateDeltaX = stage.random(0.3, 0.7);
-}
-
-CanvasStar.prototype._draw = function()
-{
- this._context.save();
- this._context.translate(this._center.x, this._center.y);
-
- this._context.fillStyle = 'yellow';
- this._context.strokeStyle = 'white';
-
- this._context.lineWidth = 1;
-
- this._context.beginPath();
- this._context.moveTo( 0, -this._size.y / 2);
- this._context.lineTo(+this._size.x / 20 - this._rotateX / 5, -this._size.y / 10);
- this._context.lineTo(+this._size.x / 4 - this._rotateX, 0);
- this._context.lineTo(+this._size.x / 20 - this._rotateX / 5, +this._size.y / 10);
- this._context.lineTo( 0, +this._size.y / 2);
- this._context.lineTo(-this._size.x / 20 + this._rotateX / 5, +this._size.y / 10);
- this._context.lineTo(-this._size.x / 4 + this._rotateX, 0);
- this._context.lineTo(-this._size.x / 20 + this._rotateX / 5, -this._size.y / 10);
- this._context.lineTo( 0, -this._size.y / 2);
-
- this._context.fill();
- this._context.stroke();
- this._context.closePath();
- this._context.restore();
-}
-
-CanvasStar.prototype.animate = function(timeDelta)
-{
- this._rotateX += this._rotateDeltaX;
-
- if (this._rotateX > this._size.x / 4 || this._rotateX < -this._size.x / 4) {
- this._rotateDeltaX = -this._rotateDeltaX;
- this._rotateX += this._rotateDeltaX;
- }
-
- this._draw();
-}
-
-function CanvasStarsStage(element, options)
-{
- Stage.call(this, element, options);
- this.context = this.element.getContext("2d");
-
- this._objects = [];
-}
-
-CanvasStarsStage.prototype = Object.create(Stage.prototype);
-CanvasStarsStage.prototype.constructor = CanvasStarsStage;
-
-CanvasStarsStage.prototype.tune = function(count)
-{
- if (count == 0)
- return this._objects.length;
-
- if (count > 0) {
- for (var i = 0; i < count; ++i)
- this._objects.push(new CanvasStar(this));
- return this._objects.length;
- }
-
- count = Math.min(-count, this._objects.length);
- this._objects.splice(-count, count);
-
- return this._objects.length;
-}
-
-CanvasStarsStage.prototype.animate = function(timeDelta)
-{
- this._objects.forEach(function(object) {
- object.animate(timeDelta);
- });
-}
-
-function CanvasStarsAnimator(benchmark, options)
-{
- Animator.call(this, benchmark, options);
- this._context = benchmark._stage.context;
-}
-
-CanvasStarsAnimator.prototype = Object.create(StageAnimator.prototype);
-CanvasStarsAnimator.prototype.constructor = CanvasStarsAnimator;
-
-CanvasStarsAnimator.prototype.animate = function()
-{
- this._context.beginPath();
- this._context.fillStyle = 'black';
- this._context.rect(0, 0, this._benchmark._stage.size.width, this._benchmark._stage.size.height);
- this._context.fill();
- return StageAnimator.prototype.animate.call(this);
-}
-
-function CanvasStarsBenchmark(suite, test, options, progressBar)
-{
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
-
-CanvasStarsBenchmark.prototype = Object.create(StageBenchmark.prototype);
-CanvasStarsBenchmark.prototype.constructor = CanvasStarsBenchmark;
-
-CanvasStarsBenchmark.prototype.createStage = function(element)
-{
- // Attach the stage to the benchmark.
- return new CanvasStarsStage(element, this._options);
-}
-
-CanvasStarsBenchmark.prototype.createAnimator = function()
-{
- // Attach the animator to the benchmark.
- return new CanvasStarsAnimator(this, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- // This function is called from the test harness which starts the
- // test by creating your benchmark object.
- return new CanvasStarsBenchmark(suite, test, options, progressBar);
-}
\ No newline at end of file
<html>
<head>
<link rel="stylesheet" type="text/css" href="resources/stage.css">
+</head>
+<body>
+ <canvas id="stage"></canvas>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/canvas-stage.js"></script>
<script src="resources/canvas-tests.js"></script>
-</head>
-<body>
- <canvas id="stage"></canvas>
</body>
</html>
-function SimpleCanvasStage(element, options, canvasObject)
-{
- Stage.call(this, element, options);
- this.options = options;
- this.context = this.element.getContext("2d");
- this.canvasObject = canvasObject;
- this._objects = [];
-}
-SimpleCanvasStage.prototype = Object.create(Stage.prototype);
-SimpleCanvasStage.prototype.constructor = SimpleCanvasStage;
-SimpleCanvasStage.prototype.tune = function(count)
-{
- if (count == 0)
- return this._objects.length;
+SimpleCanvasStage = Utilities.createSubclass(Stage,
+ function(canvasObject)
+ {
+ Stage.call(this);
+ this._canvasObject = canvasObject;
+ this.objects = [];
+ }, {
- if (count > 0) {
- // For path-based tests, use the object length as a maximum coordinate value
- // to make it easier to see what the test is doing
- var coordinateMaximum = Math.max(this._objects.length, 200);
- for (var i = 0; i < count; ++i) {
- this._objects.push(new this.canvasObject(this, coordinateMaximum));
- }
- return this._objects.length;
- }
-
- count = Math.min(-count, this._objects.length);
- this._objects.splice(0, count);
- return this._objects.length;
-}
-SimpleCanvasStage.prototype.animate = function()
-{
- var context = this.context;
- this._objects.forEach(function(object) {
- object.draw(context);
- });
-}
+ initialize: function(benchmark)
+ {
+ Stage.prototype.initialize.call(this, benchmark);
+ this.context = this.element.getContext("2d");
+ },
-function SimpleCanvasAnimator(benchmark, options)
-{
- StageAnimator.call(this, benchmark, options);
- this._context = benchmark._stage.context;
-}
+ tune: function(count)
+ {
+ if (count == 0)
+ return this.objects.length;
-SimpleCanvasAnimator.prototype = Object.create(StageAnimator.prototype);
-SimpleCanvasAnimator.prototype.constructor = SimpleCanvasAnimator;
-SimpleCanvasAnimator.prototype.animate = function()
-{
- this._context.clearRect(0, 0, this._benchmark._stage.size.x, this._benchmark._stage.size.y);
- return StageAnimator.prototype.animate.call(this, this._options);
-}
+ if (count > 0) {
+ for (var i = 0; i < count; ++i)
+ this.objects.push(new this._canvasObject(this));
+ return this.objects.length;
+ }
+ count = Math.min(-count, this.objects.length);
+ this.objects.splice(0, count);
+ return this.objects.length;
+ },
-function SimpleCanvasBenchmark(suite, test, options, progressBar) {
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
-SimpleCanvasBenchmark.prototype = Object.create(StageBenchmark.prototype);
-SimpleCanvasBenchmark.prototype.constructor = SimpleCanvasBenchmark;
-SimpleCanvasBenchmark.prototype.createAnimator = function() {
- return new SimpleCanvasAnimator(this, this._options);
-}
+ animate: function()
+ {
+ var context = this.context;
+ context.clearRect(0, 0, this.size.x, this.size.y);
+ this.objects.forEach(function(object) {
+ object.draw(context);
+ });
+ },
+ complexity: function()
+ {
+ return this.objects.length;
+ }
+});
context.strokeStyle = this._color;
context.lineWidth = this._lineWidth;
- this._length+=Math.sin(Date.now()/100*this._omega);
+ this._length += Math.sin(Date.now()/100*this._omega);
context.beginPath();
context.moveTo(this._startX, this._startY);
this._point = new Point(distanceX * (randX + (randY % 2) / 2), distanceY * (randY + .5));
- this._radius = 20 + Math.pow(Math.random(), 5) * (Math.min(distanceX, distanceY) / 1.6);
+ this._radius = 20 + Math.pow(Math.random(), 5) * (Math.min(distanceX, distanceY) / 1.8);
this._startAngle = stage.randomAngle();
this._endAngle = stage.randomAngle();
this._omega = (Math.random() - 0.5) * 0.3;
}
};
+// CanvasLinePoint contains no draw() method since it is either moveTo or
+// lineTo depending on its index.
function CanvasLinePoint(stage, coordinateMaximum)
{
var X_LOOPS = 40;
var offset = offsets[Math.floor(Math.random() * offsets.length)];
this.coordinate = new Point(X_LOOPS/2, Y_LOOPS/2);
- if (stage._objects.length) {
- var head = stage._objects[stage._objects.length - 1].coordinate;
+ if (stage.objects.length) {
+ var head = stage.objects[stage.objects.length - 1].coordinate;
this.coordinate.x = head.x;
this.coordinate.y = head.y;
}
var xOff = .25 * (this.coordinate.y % 2);
var randX = (xOff + this.coordinate.x) * stage.size.x / X_LOOPS;
var randY = this.coordinate.y * stage.size.y / Y_LOOPS;
- var colors = ["#101010", "#808080", "#c0c0c0", "#e01040"];
- this._color = colors[Math.floor(Math.random() * colors.length)];
-
- this._width = Math.pow(Math.random(), 5) * 20 + 1;
- this._isSplit = Math.random() > 0.9;
- this._point = new Point(randX, randY);
+ var colors = ["#101010", "#808080", "#c0c0c0", "#101010", "#808080", "#c0c0c0", "#e01040"];
+ this.color = colors[Math.floor(Math.random() * colors.length)];
+ this.width = Math.pow(Math.random(), 5) * 20 + 1;
+ this.isSplit = Math.random() > 0.9;
+ this.point = new Point(randX, randY);
}
-CanvasLinePoint.prototype.draw = function(context, stage)
-{
- context.lineTo(this._point.x, this._point.y);
-};
-
-
// === STAGES ===
-function SimpleCanvasPathStrokeStage(element, options, canvasObject)
-{
- SimpleCanvasStage.call(this, element, options, canvasObject);
- this.context.lineCap = options["lineCap"] || "butt";
- this.context.lineJoin = options["lineJoin"] || "bevel";
-}
-SimpleCanvasPathStrokeStage.prototype = Object.create(SimpleCanvasStage.prototype);
-SimpleCanvasPathStrokeStage.prototype.constructor = SimpleCanvasPathStrokeStage;
-SimpleCanvasPathStrokeStage.prototype.animate = function() {
- var context = this.context;
- var stage = this;
-
- context.beginPath();
- this._objects.forEach(function(object, index) {
- if (index == 0) {
- context.lineWidth = object._width;
- context.strokeStyle = object._color;
- context.moveTo(object._point.x, object._point.y);
- } else {
- if (object._isSplit) {
- context.stroke();
-
- context.lineWidth = object._width;
- context.strokeStyle = object._color;
- context.beginPath();
- }
-
- if (Math.random() > 0.999)
- object._isSplit = !object._isSplit;
-
- object.draw(context);
+CanvasLineSegmentStage = Utilities.createSubclass(SimpleCanvasStage,
+ function()
+ {
+ SimpleCanvasStage.call(this, CanvasLineSegment);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ SimpleCanvasStage.prototype.initialize.call(this, benchmark);
+ this.context.lineCap = benchmark.options["lineCap"] || "butt";
+ this.circleRadius = this.size.x / 3 / 2 - 20;
+ },
+
+ animate: function()
+ {
+ var context = this.context;
+ var stage = this;
+
+ context.clearRect(0, 0, this.size.x, this.size.y);
+ context.lineWidth = 30;
+ for(var i = 0; i < 3; i++) {
+ context.strokeStyle = ["#e01040", "#10c030", "#e05010"][i];
+ context.fillStyle = ["#70051d", "#016112", "#702701"][i];
+ context.beginPath();
+ context.arc((0.5 + i) / 3 * stage.size.x, stage.size.y/2, stage.circleRadius, 0, Math.PI*2);
+ context.stroke();
+ context.fill();
}
- });
- context.stroke();
-}
-function CanvasLineSegmentStage(element, options)
-{
- SimpleCanvasStage.call(this, element, options, CanvasLineSegment);
- this.context.lineCap = options["lineCap"] || "butt";
- this.circleRadius = this.size.x / 3 / 2 - 20;
-}
-CanvasLineSegmentStage.prototype = Object.create(SimpleCanvasStage.prototype);
-CanvasLineSegmentStage.prototype.constructor = CanvasLineSegmentStage;
-CanvasLineSegmentStage.prototype.animate = function()
-{
- var context = this.context;
- var stage = this;
-
- context.lineWidth = 30;
- for(var i = 0; i < 3; i++) {
- context.strokeStyle = ["#e01040", "#10c030", "#e05010"][i];
- context.fillStyle = ["#70051d", "#016112", "#702701"][i];
+ this.objects.forEach(function(object) {
+ object.draw(context);
+ });
+ }
+});
+
+CanvasLinePathStage = Utilities.createSubclass(SimpleCanvasStage,
+ function()
+ {
+ SimpleCanvasStage.call(this, CanvasLinePoint);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ SimpleCanvasStage.prototype.initialize.call(this, benchmark);
+ this.context.lineJoin = benchmark.options["lineJoin"] || "bevel";
+ this.context.lineCap = benchmark.options["lineCap"] || "butt";
+ },
+
+ animate: function() {
+ var context = this.context;
+ var stage = this;
+
+ context.clearRect(0, 0, this.size.x, this.size.y);
context.beginPath();
- context.arc((0.5 + i) / 3 * stage.size.x, stage.size.y/2, stage.circleRadius, 0, Math.PI*2);
+ this.objects.forEach(function(object, index) {
+ if (index == 0) {
+ context.lineWidth = object.width;
+ context.strokeStyle = object.color;
+ context.moveTo(object.point.x, object.point.y);
+ } else {
+ if (object.isSplit) {
+ context.stroke();
+
+ context.lineWidth = object.width;
+ context.strokeStyle = object.color;
+ context.beginPath();
+ }
+
+ context.lineTo(object.point.x, object.point.y);
+
+ if (Math.random() > 0.999)
+ object.isSplit = !object.isSplit;
+ }
+ });
context.stroke();
- context.fill();
}
-
- this._objects.forEach(function(object) {
- object.draw(context);
- });
-}
-
-function CanvasLinePathStage(element, options)
-{
- SimpleCanvasPathStrokeStage.call(this, element, options, CanvasLinePoint);
- this.context.lineJoin = options["lineJoin"] || "bevel";
- this.context.lineCap = options["lineCap"] || "butt";
-}
-CanvasLinePathStage.prototype = Object.create(SimpleCanvasPathStrokeStage.prototype);
-CanvasLinePathStage.prototype.constructor = CanvasLinePathStage;
+});
// === BENCHMARK ===
-function CanvasPathBenchmark(suite, test, options, progressBar)
-{
- SimpleCanvasBenchmark.call(this, suite, test, options, progressBar);
-}
-CanvasPathBenchmark.prototype = Object.create(SimpleCanvasBenchmark.prototype);
-CanvasPathBenchmark.prototype.constructor = CanvasPathBenchmark;
-CanvasPathBenchmark.prototype.createStage = function(element)
-{
- switch (this._options["pathType"]) {
- case "line":
- return new CanvasLineSegmentStage(element, this._options);
- case "arcs":
- return new SimpleCanvasStage(element, this._options, CanvasArc);
- case "linePath":
- return new CanvasLinePathStage(element, this._options);
+CanvasPathBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ var stage;
+ switch (options["pathType"]) {
+ case "line":
+ stage = new CanvasLineSegmentStage();
+ break;
+ case "linePath":
+ stage = new CanvasLinePathStage();
+ break;
+ case "arcs":
+ stage = new SimpleCanvasStage(CanvasArc);
+ break;
+ }
+
+ Benchmark.call(this, stage, options);
}
-}
+);
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- return new CanvasPathBenchmark(suite, test, options, progressBar);
-}
+window.benchmarkClass = CanvasPathBenchmark;
})();
\ No newline at end of file
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <canvas id="stage"></canvas>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/canvas-electrons.js"></script>
-</head>
-<body>
- <canvas id="stage"></canvas>
</body>
</html>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/canvas-stars.js"></script>
</head>
<body>
<!DOCTYPE html>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="../resources/stage.css">
<style>
img {
position: absolute;
height: 80px;
}
</style>
- <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <div id="stage"></div>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="../bouncing-particles/resources/bouncing-particles.js"></script>
<script src="resources/compositing-transforms.js"></script>
-</head>
-<body>
- <div id="stage"></div>
</body>
</html>
--- /dev/null
+(function() {
+
+function CanvasElectron(stage)
+{
+ this._context = stage.context;
+ this._stageSize = stage.size;
+
+ var minSide = Math.min(this._stageSize.width, this._stageSize.height);
+ var radiusX = stage.random(minSide / 8, 7 * minSide / 16);
+ var radiusY = stage.random(minSide / 8, 3 * radiusX / 4);
+ this._orbitRadiuses = new Point(radiusX, radiusY);
+ this._radius = stage.random(5, 15);
+ this._direction = stage.randomInt(0, 2);
+ this._angle = stage.randomInt(0, 360);
+ this._color = stage.randomColor();
+ this._rotater = stage.randomRotater();
+ this._rotater.next(stage.random(0, this._rotater.interval));
+}
+
+CanvasElectron.prototype = {
+ _draw: function()
+ {
+ // Calculate the position of the object on the ellipse.
+ var angle = this._direction ? this._rotater.degree() : 360 - this._rotater.degree();
+ var position = this._stageSize.center.subtract(Point.pointOnEllipse(angle, this._orbitRadiuses));
+
+ this._context.save();
+ this._context.translate(this._stageSize.center.x, this._stageSize.center.y);
+ this._context.rotate(this._angle * Math.PI / 180);
+ this._context.translate(-this._stageSize.center.x, -this._stageSize.center.y);
+
+ // Set the stroke and the fill colors
+ this._context.strokeStyle = "rgba(192, 192, 192, 0.9)";
+ this._context.fillStyle = this._color;
+
+ // Draw the orbit of the object.
+ this._context.beginPath();
+ this._context.ellipse(this._stageSize.center.x, this._stageSize.center.y, this._orbitRadiuses.x, this._orbitRadiuses.y, 0, 0, 2 * Math.PI);
+ this._context.stroke();
+
+ // Draw the object.
+ this._context.beginPath();
+ this._context.arc(position.x, position.y, this._radius, 0, Math.PI * 2, true);
+ this._context.fill();
+ this._context.restore();
+ },
+
+ animate: function(timeDelta)
+ {
+ this._rotater.next(timeDelta / 100);
+ this._draw();
+ }
+};
+
+CanvasElectronsStage = Utilities.createSubclass(Stage,
+ function()
+ {
+ Stage.call(this);
+ this._electrons = [];
+ }, {
+
+ initialize: function(benchmark)
+ {
+ Stage.prototype.initialize.call(this, benchmark);
+ this.context = this.element.getContext("2d");
+ },
+
+ tune: function(count)
+ {
+ if (count == 0)
+ return this._electrons.length;
+
+ if (count > 0) {
+ for (var i = 0; i < count; ++i)
+ this._electrons.push(new CanvasElectron(this));
+ return this._electrons.length;
+ }
+
+ count = Math.min(-count, this._electrons.length);
+ this._electrons.splice(-count, count);
+
+ return this._electrons.length;
+ },
+
+ animate: function(timeDelta)
+ {
+ this.context.clearRect(0, 0, this.size.x, this.size.y);
+
+ // Draw a big star in the middle.
+ this.context.fillStyle = "orange";
+ this.context.beginPath();
+ this.context.arc(this.size.center.x, this.size.center.y, 50, 0, Math.PI * 2, true);
+ this.context.fill();
+
+ this._electrons.forEach(function(electron) {
+ electron.animate(timeDelta);
+ });
+ }
+});
+
+CanvasElectronsBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new CanvasElectronsStage(), options);
+ }
+);
+
+window.benchmarkClass = CanvasElectronsBenchmark;
+
+})();
\ No newline at end of file
--- /dev/null
+(function() {
+
+function CanvasStar(stage)
+{
+ this._context = stage.context;
+
+ this._size = stage.randomSquareSize(5, 20);
+ this._center = stage.randomPosition(stage.size.subtract(this._size)).add(this._size.center);
+ this._rotateX = 0;
+ this._rotateDeltaX = stage.random(0.3, 0.7);
+}
+
+CanvasStar.prototype = {
+ _draw: function()
+ {
+ this._context.save();
+ this._context.translate(this._center.x, this._center.y);
+
+ this._context.fillStyle = 'yellow';
+ this._context.strokeStyle = 'white';
+
+ this._context.lineWidth = 1;
+
+ this._context.beginPath();
+ this._context.moveTo( 0, -this._size.y / 2);
+ this._context.lineTo(+this._size.x / 20 - this._rotateX / 5, -this._size.y / 10);
+ this._context.lineTo(+this._size.x / 4 - this._rotateX, 0);
+ this._context.lineTo(+this._size.x / 20 - this._rotateX / 5, +this._size.y / 10);
+ this._context.lineTo( 0, +this._size.y / 2);
+ this._context.lineTo(-this._size.x / 20 + this._rotateX / 5, +this._size.y / 10);
+ this._context.lineTo(-this._size.x / 4 + this._rotateX, 0);
+ this._context.lineTo(-this._size.x / 20 + this._rotateX / 5, -this._size.y / 10);
+ this._context.lineTo( 0, -this._size.y / 2);
+
+ this._context.fill();
+ this._context.stroke();
+ this._context.closePath();
+ this._context.restore();
+ },
+
+ animate: function(timeDelta)
+ {
+ this._rotateX += this._rotateDeltaX;
+
+ if (this._rotateX > this._size.x / 4 || this._rotateX < -this._size.x / 4) {
+ this._rotateDeltaX = -this._rotateDeltaX;
+ this._rotateX += this._rotateDeltaX;
+ }
+
+ this._draw();
+ }
+};
+
+CanvasStarsStage = Utilities.createSubclass(Stage,
+ function()
+ {
+ Stage.call(this);
+ this._objects = [];
+ }, {
+
+ initialize: function(benchmark)
+ {
+ Stage.prototype.initialize.call(this, benchmark);
+ this.context = this.element.getContext("2d");
+ },
+
+ tune: function(count)
+ {
+ if (count == 0)
+ return this._objects.length;
+
+ if (count > 0) {
+ for (var i = 0; i < count; ++i)
+ this._objects.push(new CanvasStar(this));
+ return this._objects.length;
+ }
+
+ count = Math.min(-count, this._objects.length);
+ this._objects.splice(-count, count);
+
+ return this._objects.length;
+ },
+
+ animate: function(timeDelta)
+ {
+ this.context.beginPath();
+ this.context.fillStyle = 'black';
+ this.context.rect(0, 0, this.size.width, this.size.height);
+ this.context.fill();
+
+ this._objects.forEach(function(object) {
+ object.animate(timeDelta);
+ });
+ }
+});
+
+CanvasStarsBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new CanvasStarsStage(), options);
+ }
+);
+
+window.benchmarkClass = CanvasStarsBenchmark;
+
+})();
\ No newline at end of file
-function BouncingCompositedImage(stage)
-{
- BouncingParticle.call(this, stage);
+(function() {
- this.element = document.createElement("img");
- this.element.style.width = this._size.x + "px";
- this.element.style.height = this._size.y + "px";
- this.element.setAttribute("src", stage.imageSrc);
-
- if (stage.useFilters)
- this.element.style.filter = "hue-rotate(" + stage.randomAngle() + "rad)";
-
- stage.element.appendChild(this.element);
- this._move();
-}
+BouncingCompositedImage = Utilities.createSubclass(BouncingParticle,
+ function(stage)
+ {
+ BouncingParticle.call(this, stage);
-BouncingCompositedImage.prototype = Object.create(BouncingParticle.prototype);
-BouncingCompositedImage.prototype.constructor = BouncingCompositedImage;
+ this.element = document.createElement("img");
+ this.element.style.width = this.size.x + "px";
+ this.element.style.height = this.size.y + "px";
+ this.element.setAttribute("src", stage.imageSrc);
-BouncingCompositedImage.prototype._move = function()
-{
- this.element.style.transform = "translate3d(" + this._position.x + "px," + this._position.y + "px, 0) " + this._rotater.rotateZ();
-}
-
-BouncingCompositedImage.prototype.animate = function(timeDelta)
-{
- BouncingParticle.prototype.animate.call(this, timeDelta);
- this._move();
-}
+ if (stage.useFilters)
+ this.element.style.filter = "hue-rotate(" + stage.randomAngle() + "rad)";
-function CompositingTransformsStage(element, options)
-{
- BouncingParticlesStage.call(this, element, options);
- this.imageSrc = options["imageSrc"] || "../resources/yin-yang.svg";
- this.useFilters = options["filters"] == "yes";
-}
+ stage.element.appendChild(this.element);
+ this._move();
+ }, {
-CompositingTransformsStage.prototype = Object.create(BouncingParticlesStage.prototype);
-CompositingTransformsStage.prototype.constructor = CompositingTransformsStage;
+ _move: function()
+ {
+ this.element.style.transform = "translate3d(" + this.position.x + "px," + this.position.y + "px, 0) " + this.rotater.rotateZ();
+ },
-CompositingTransformsStage.prototype.createParticle = function()
-{
- return new BouncingCompositedImage(this);
-}
+ animate: function(timeDelta)
+ {
+ BouncingParticle.prototype.animate.call(this, timeDelta);
+ this._move();
+ }
+});
-CompositingTransformsStage.prototype.particleWillBeRemoved = function(particle)
-{
- particle.element.remove();
-}
+CompositingTransformsStage = Utilities.createSubclass(BouncingParticlesStage,
+ function()
+ {
+ BouncingParticlesStage.call(this);
+ }, {
-function CompositedTransformsBenchmark(suite, test, options, progressBar)
-{
- BouncingParticlesBenchmark.call(this, suite, test, options, progressBar);
-}
+ initialize: function(benchmark)
+ {
+ BouncingParticlesStage.prototype.initialize.call(this, benchmark);
-CompositedTransformsBenchmark.prototype = Object.create(BouncingParticlesBenchmark.prototype);
-CompositedTransformsBenchmark.prototype.constructor = CompositedTransformsBenchmark;
+ this.imageSrc = benchmark.options["imageSrc"] || "../resources/yin-yang.svg";
+ this.useFilters = benchmark.options["filters"] == "yes";
+ },
-CompositedTransformsBenchmark.prototype.createStage = function(element)
-{
- return new CompositingTransformsStage(element, this._options);
-}
+ createParticle: function()
+ {
+ return new BouncingCompositedImage(this);
+ },
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- return new CompositedTransformsBenchmark(suite, test, options, progressBar);
-}
+ particleWillBeRemoved: function(particle)
+ {
+ particle.element.remove();
+ }
+});
+
+CompositedTransformsBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new CompositingTransformsStage(), options);
+ }
+);
+
+window.benchmarkClass = CompositedTransformsBenchmark;
+
+})();
+function Rotater(rotateInterval)
+{
+ this._timeDelta = 0;
+ this._rotateInterval = rotateInterval;
+}
+
+Rotater.prototype =
+{
+ get interval()
+ {
+ return this._rotateInterval;
+ },
+
+ next: function(timeDelta)
+ {
+ this._timeDelta = (this._timeDelta + timeDelta) % this._rotateInterval;
+ },
+
+ degree: function()
+ {
+ return (360 * this._timeDelta) / this._rotateInterval;
+ },
+
+ rotateZ: function()
+ {
+ return "rotateZ(" + Math.floor(this.degree()) + "deg)";
+ },
+
+ rotate: function(center)
+ {
+ return "rotate(" + Math.floor(this.degree()) + ", " + center.x + "," + center.y + ")";
+ }
+};
+
function BenchmarkState(testInterval)
{
this._currentTimeOffset = 0;
WARMING: 0,
SAMPLING: 1,
FINISHED: 2,
- messages: [
- Strings.text.runningState.warming,
- Strings.text.runningState.sampling,
- Strings.text.runningState.finished
- ]
}
BenchmarkState.prototype =
{
return stage * this._stageInterval;
},
-
+
_message: function(stage, timeOffset)
{
if (stage == BenchmarkState.stages.FINISHED)
+ Math.floor((timeOffset - this._timeOffset(stage)) / 1000) + "/"
+ Math.floor((this._timeOffset(stage + 1) - this._timeOffset(stage)) / 1000) + ")";
},
-
+
update: function(currentTimeOffset)
{
this._currentTimeOffset = currentTimeOffset;
},
-
+
samplingTimeOffset: function()
{
return this._timeOffset(BenchmarkState.stages.SAMPLING);
},
-
+
currentStage: function()
{
for (var stage = BenchmarkState.stages.WARMING; stage < BenchmarkState.stages.FINISHED; ++stage) {
return stage;
}
return BenchmarkState.stages.FINISHED;
+ }
+}
+
+
+function Stage() {}
+
+Stage.prototype =
+{
+ initialize: function(benchmark)
+ {
+ this._benchmark = benchmark;
+ this._element = document.getElementById("stage");
+ this._element.setAttribute("width", document.body.offsetWidth);
+ this._element.setAttribute("height", document.body.offsetHeight);
+ this._size = Point.elementClientSize(this._element).subtract(Insets.elementPadding(this._element).size);
+ },
+
+ get element()
+ {
+ return this._element;
+ },
+
+ get size()
+ {
+ return this._size;
+ },
+
+ complexity: function()
+ {
+ return 0;
+ },
+
+ random: function(min, max)
+ {
+ return (Math.random() * (max - min)) + min;
+ },
+
+ randomBool: function()
+ {
+ return !!Math.round(this.random(0, 1));
+ },
+
+ randomInt: function(min, max)
+ {
+ return Math.round(this.random(min, max));
+ },
+
+ randomPosition: function(maxPosition)
+ {
+ return new Point(this.randomInt(0, maxPosition.x), this.randomInt(0, maxPosition.y));
+ },
+
+ randomSquareSize: function(min, max)
+ {
+ var side = this.random(min, max);
+ return new Point(side, side);
+ },
+
+ randomVelocity: function(maxVelocity)
+ {
+ return this.random(maxVelocity / 8, maxVelocity);
+ },
+
+ randomAngle: function()
+ {
+ return this.random(0, Math.PI * 2);
+ },
+
+ randomColor: function()
+ {
+ var min = 32;
+ var max = 256 - 32;
+ return "#"
+ + this.randomInt(min, max).toString(16)
+ + this.randomInt(min, max).toString(16)
+ + this.randomInt(min, max).toString(16);
},
-
- currentMessage: function()
+
+ randomRotater: function()
{
- return this._message(this.currentStage(), this._currentTimeOffset);
+ return new Rotater(this.random(1000, 10000));
},
-
- currentProgress: function()
+
+ tune: function()
{
- return this._currentTimeOffset / this._timeOffset(BenchmarkState.stages.FINISHED);
+ throw "Not implemented";
+ },
+
+ animate: function()
+ {
+ throw "Not implemented";
+ },
+
+ clear: function()
+ {
+ return this.tune(-this.tune(0));
}
-}
+};
-function Animator(benchmark, options)
+function Animator()
{
- this._benchmark = benchmark;
- this._options = options;
-
this._frameCount = 0;
this._dropFrameCount = 1;
- this._measureFrameCount = 3;
+ this._measureFrameCount = 3;
this._referenceTime = 0;
this._currentTimeOffset = 0;
this._estimator = new KalmanEstimator(60);
Animator.prototype =
{
+ initialize: function(benchmark)
+ {
+ this._benchmark = benchmark;
+ this._estimateFrameRate = benchmark.options["estimated-frame-rate"];
+ },
+
+ get benchmark()
+ {
+ return this._benchmark;
+ },
+
timeDelta: function()
{
return this._currentTimeOffset - this._startTimeOffset;
},
-
- animate: function()
+
+ _shouldRequestAnotherFrame: function()
{
var currentTime = performance.now();
// Get the average FPS of _measureFrameCount frames over measureTimeDelta.
var measureTimeDelta = this._currentTimeOffset - this._measureTimeOffset;
var currentFrameRate = Math.floor(1000 / (measureTimeDelta / this._measureFrameCount));
-
+
// Use Kalman filter to get a more non-fluctuating frame rate.
- if (this._options["estimated-frame-rate"])
+ if (this._estimateFrameRate)
currentFrameRate = this._estimator.estimate(currentFrameRate);
-
+
// Adjust the test to reach the desired FPS.
var result = this._benchmark.update(this._currentTimeOffset, this.timeDelta(), currentFrameRate);
-
+
// Start the next drop/measure cycle.
this._frameCount = 0;
-
+
// If result == 0, no more requestAnimationFrame() will be invoked.
return result;
},
-
- animateLoop: function(timestamp)
+
+ animateLoop: function()
{
- if (this.animate())
+ if (this._shouldRequestAnotherFrame()) {
+ this._benchmark.stage.animate(this.timeDelta());
requestAnimationFrame(this.animateLoop.bind(this));
+ }
}
}
-function Benchmark(options)
+function Benchmark(stage, options)
{
this._options = options;
- this._recordInterval = 200;
- this._isSampling = false;
+ this._stage = stage;
+ this._stage.initialize(this);
+ this._animator = new Animator();
+ this._animator.initialize(this);
+
+ this._recordInterval = 200;
+ this._isSampling = false;
this._controller = new PIDController(this._options["frame-rate"]);
this._sampler = new Sampler(2);
this._state = new BenchmarkState(this._options["test-interval"] * 1000);
Benchmark.prototype =
{
+ get options()
+ {
+ return this._options;
+ },
+
+ get stage()
+ {
+ return this._stage;
+ },
+
+ get animator()
+ {
+ return this._animator;
+ },
+
// Called from the load event listener or from this.run().
start: function()
{
this._animator.animateLoop();
},
-
+
// Called from the animator to adjust the complexity of the test.
update: function(currentTimeOffset, timeDelta, currentFrameRate)
{
this._state.update(currentTimeOffset);
-
+
var stage = this._state.currentStage();
if (stage == BenchmarkState.stages.FINISHED) {
- this.clear();
+ this._stage.clear();
return false;
}
var tuneValue = 0;
if (this._options["adjustment"] == "fixed") {
if (this._options["complexity"]) {
- // this.tune(0) returns the current complexity of the test.
- tuneValue = this._options["complexity"] - this.tune(0);
+ // this._stage.tune(0) returns the current complexity of the test.
+ tuneValue = this._options["complexity"] - this._stage.tune(0);
}
}
else if (!(this._isSampling && this._options["adjustment"] == "fixed-after-warmup")) {
tuneValue = tuneValue > 0 ? Math.floor(tuneValue) : Math.ceil(tuneValue);
}
- var currentComplexity = this.tune(tuneValue);
+ var currentComplexity = this._stage.tune(tuneValue);
this.record(currentTimeOffset, currentComplexity, currentFrameRate);
return true;
},
-
+
record: function(currentTimeOffset, currentComplexity, currentFrameRate)
{
this._sampler.sample(currentTimeOffset, [currentComplexity, currentFrameRate]);
-
+
if (typeof this._recordTimeOffset == "undefined")
this._recordTimeOffset = currentTimeOffset;
if (stage != BenchmarkState.stages.FINISHED && currentTimeOffset < this._recordTimeOffset + this._recordInterval)
return;
- this.showResults(this._state.currentProgress(), this._state.currentMessage());
this._recordTimeOffset = currentTimeOffset;
},
-
+
run: function()
{
this.start();
return promise.resolve(self._sampler);
setTimeout(resolveWhenFinished.bind(self), 50);
}
-
+
resolveWhenFinished();
return promise;
}
-}
-
-window.benchmarkClient = {};
-
-// This event listener runs the test if it is loaded outside the benchmark runner.
-window.addEventListener("load", function()
-{
- if (window.self !== window.top)
- return;
- window.benchmark = window.benchmarkClient.create(null, null, 30000, 50, null, null);
- window.benchmark.start();
-});
-
-// This function is called from the suite controller run-callback when running the benchmark runner.
-window.runBenchmark = function(suite, test, options, progressBar)
-{
- var benchmarkOptions = { complexity: test.complexity };
- benchmarkOptions = Utilities.mergeObjects(benchmarkOptions, options);
- benchmarkOptions = Utilities.mergeObjects(benchmarkOptions, Utilities.parseParameters());
- window.benchmark = window.benchmarkClient.create(suite, test, benchmarkOptions, progressBar);
- return window.benchmark.run();
-}
+};
+++ /dev/null
-function Rotater(rotateInterval)
-{
- this._timeDelta = 0;
- this._rotateInterval = rotateInterval;
-}
-
-Rotater.prototype =
-{
- get interval()
- {
- return this._rotateInterval;
- },
-
- next: function(timeDelta)
- {
- this._timeDelta = (this._timeDelta + timeDelta) % this._rotateInterval;
- },
-
- degree: function()
- {
- return (360 * this._timeDelta) / this._rotateInterval;
- },
-
- rotateZ: function()
- {
- return "rotateZ(" + Math.floor(this.degree()) + "deg)";
- },
-
- rotate: function(center)
- {
- return "rotate(" + Math.floor(this.degree()) + ", " + center.x + "," + center.y + ")";
- }
-}
-
-function Stage(element, options)
-{
- this.element = element;
- this._size = Point.elementClientSize(element).subtract(Insets.elementPadding(element).size);
-}
-
-Stage.prototype =
-{
- get size()
- {
- return this._size
- },
-
- random: function(min, max)
- {
- return (Math.random() * (max - min)) + min;
- },
-
- randomBool: function()
- {
- return !!Math.round(this.random(0, 1));
- },
-
- randomInt: function(min, max)
- {
- return Math.round(this.random(min, max));
- },
-
- randomPosition: function(maxPosition)
- {
- return new Point(this.randomInt(0, maxPosition.x), this.randomInt(0, maxPosition.y));
- },
-
- randomSquareSize: function(min, max)
- {
- var side = this.random(min, max);
- return new Point(side, side);
- },
-
- randomVelocity: function(maxVelocity)
- {
- return this.random(maxVelocity / 8, maxVelocity);
- },
-
- randomAngle: function()
- {
- return this.random(0, Math.PI * 2);
- },
-
- randomColor: function()
- {
- var min = 32;
- var max = 256 - 32;
- return "#"
- + this.randomInt(min, max).toString(16)
- + this.randomInt(min, max).toString(16)
- + this.randomInt(min, max).toString(16);
- },
-
- randomRotater: function()
- {
- return new Rotater(this.random(1000, 10000));
- },
-
- tune: function()
- {
- throw "Not implemented";
- },
-
- animate: function()
- {
- throw "Not implemented";
- },
-
- clear: function()
- {
- return this.tune(-this.tune(0));
- }
-}
-
-function StageAnimator(benchmark, options)
-{
- Animator.call(this, benchmark, options);
-};
-
-StageAnimator.prototype = Object.create(Animator.prototype);
-StageAnimator.prototype.constructor = StageAnimator;
-
-StageAnimator.prototype.animate = function()
-{
- if (!Animator.prototype.animate.call(this))
- return false;
- this._benchmark._stage.animate(this.timeDelta());
- return true;
-}
-
-function StageBenchmark(suite, test, options, progressBar)
-{
- Benchmark.call(this, options);
-
- var element = document.getElementById("stage");
- element.setAttribute("width", document.body.offsetWidth);
- element.setAttribute("height", document.body.offsetHeight);
-
- this._stage = this.createStage(element);
- this._animator = this.createAnimator();
- this._suite = suite;
- this._test = test;
- this._progressBar = progressBar;
-}
-
-StageBenchmark.prototype = Object.create(Benchmark.prototype);
-StageBenchmark.prototype.constructor = StageBenchmark;
-
-StageBenchmark.prototype.createStage = function(element)
-{
- return new Stage(element, this._options);
-}
-
-StageBenchmark.prototype.createAnimator = function()
-{
- return new StageAnimator(this, this._options);
-}
-
-StageBenchmark.prototype.tune = function(count)
-{
- return this._stage.tune(count);
-}
-
-StageBenchmark.prototype.clear = function()
-{
- return this._stage.clear();
-}
-
-StageBenchmark.prototype.showResults = function(progress, message)
-{
- if (!this._progressBar || !this._test)
- return;
-
- this._progressBar.setPos(progress);
-}
+(function() {
+
// === PAINT OBJECTS ===
function CanvasLineSegment(stage) {
// === STAGES ===
-function SimpleCanvasPathStrokeStage(element, options, canvasObject) {
- SimpleCanvasStage.call(this, element, options, canvasObject);
-}
-SimpleCanvasPathStrokeStage.prototype = Object.create(SimpleCanvasStage.prototype);
-SimpleCanvasPathStrokeStage.prototype.constructor = SimpleCanvasPathStrokeStage;
-SimpleCanvasPathStrokeStage.prototype.animate = function() {
- var context = this.context;
- context.lineWidth = this.randomInt(1, 20);
- context.strokeStyle = this.randomColor();
- context.beginPath();
- context.moveTo(0,0);
- this._objects.forEach(function(object) {
- object.draw(context);
- });
- context.stroke();
-}
+SimpleCanvasPathStrokeStage = Utilities.createSubclass(SimpleCanvasStage,
+ function(canvasObject) {
+ SimpleCanvasStage.call(this, canvasObject);
+ }, {
-function SimpleCanvasPathFillStage(element, options, canvasObject) {
- SimpleCanvasStage.call(this, element, options, canvasObject);
-}
-SimpleCanvasPathFillStage.prototype = Object.create(SimpleCanvasStage.prototype);
-SimpleCanvasPathFillStage.prototype.constructor = SimpleCanvasPathFillStage;
-SimpleCanvasPathFillStage.prototype.animate = function() {
- var context = this.context;
- context.fillStyle = this.randomColor();
- context.beginPath();
- context.moveTo(0,0);
- this._objects.forEach(function(object) {
- object.draw(context);
- });
- context.fill();
-}
+ animate: function()
+ {
+ var context = this.context;
+ context.clearRect(0, 0, this.size.x, this.size.y);
+ context.lineWidth = this.randomInt(1, 20);
+ context.strokeStyle = this.randomColor();
+ context.beginPath();
+ context.moveTo(0,0);
+ this.objects.forEach(function(object) {
+ object.draw(context);
+ });
+ context.stroke();
+ }
+});
-function CanvasLineSegmentStage(element, options)
-{
- SimpleCanvasStage.call(this, element, options, CanvasLineSegment);
- this.context.lineCap = options["lineCap"] || "butt";
-}
-CanvasLineSegmentStage.prototype = Object.create(SimpleCanvasStage.prototype);
-CanvasLineSegmentStage.prototype.constructor = CanvasLineSegmentStage;
+SimpleCanvasPathFillStage = Utilities.createSubclass(SimpleCanvasStage,
+ function(canvasObject) {
+ SimpleCanvasStage.call(this, canvasObject);
+ }, {
-function CanvasLinePathStage(element, options)
-{
- SimpleCanvasPathStrokeStage.call(this, element, options, CanvasLinePoint);
- this.context.lineJoin = options["lineJoin"] || "bevel";
-}
-CanvasLinePathStage.prototype = Object.create(SimpleCanvasPathStrokeStage.prototype);
-CanvasLinePathStage.prototype.constructor = CanvasLinePathStage;
-
-function CanvasLineDashStage(element, options)
-{
- SimpleCanvasStage.call(this, element, options, CanvasLinePoint);
- this.context.setLineDash([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
- this.context.lineWidth = 1;
- this.context.strokeStyle = "#000";
- this._step = 0;
-}
-CanvasLineDashStage.prototype = Object.create(SimpleCanvasStage.prototype);
-CanvasLineDashStage.prototype.constructor = CanvasLineDashStage;
-CanvasLineDashStage.prototype.animate = function() {
- var context = this.context;
- context.lineDashOffset = this._step++;
- context.beginPath();
- context.moveTo(0,0);
- this._objects.forEach(function(object) {
- object.draw(context);
- });
- context.stroke();
-};
+ animate: function()
+ {
+ var context = this.context;
+ context.clearRect(0, 0, this.size.x, this.size.y);
+ context.fillStyle = this.randomColor();
+ context.beginPath();
+ context.moveTo(0,0);
+ this.objects.forEach(function(object) {
+ object.draw(context);
+ });
+ context.fill();
+ }
+});
-// === BENCHMARK ===
+CanvasLineSegmentStage = Utilities.createSubclass(SimpleCanvasStage,
+ function()
+ {
+ SimpleCanvasStage.call(this, CanvasLineSegment);
+ }, {
-function CanvasPathBenchmark(suite, test, options, progressBar) {
- SimpleCanvasBenchmark.call(this, suite, test, options, progressBar);
-}
-CanvasPathBenchmark.prototype = Object.create(SimpleCanvasBenchmark.prototype);
-CanvasPathBenchmark.prototype.constructor = CanvasPathBenchmark;
-CanvasPathBenchmark.prototype.createStage = function(element)
-{
- switch (this._options["pathType"]) {
- case "line":
- return new CanvasLineSegmentStage(element, this._options);
- case "linePath": {
- if ("lineJoin" in this._options)
- return new CanvasLinePathStage(element, this._options);
- if ("lineDash" in this._options)
- return new CanvasLineDashStage(element, this._options);
- break;
+ initialize: function(benchmark)
+ {
+ SimpleCanvasStage.prototype.initialize.call(this, benchmark);
+ this.context.lineCap = benchmark.options["lineCap"] || "butt";
}
- case "quadratic":
- return new SimpleCanvasStage(element, this._options, CanvasQuadraticSegment);
- case "quadraticPath":
- return new SimpleCanvasPathStrokeStage(element, this._options, CanvasQuadraticPoint);
- case "bezier":
- return new SimpleCanvasStage(element, this._options, CanvasBezierSegment);
- case "bezierPath":
- return new SimpleCanvasPathStrokeStage(element, this._options, CanvasBezierPoint);
- case "arcTo":
- return new SimpleCanvasStage(element, this._options, CanvasArcToSegment);
- case "arc":
- return new SimpleCanvasStage(element, this._options, CanvasArcSegment);
- case "rect":
- return new SimpleCanvasStage(element, this._options, CanvasRect);
- case "lineFill":
- return new SimpleCanvasPathFillStage(element, this._options, CanvasLinePoint);
- case "quadraticFill":
- return new SimpleCanvasPathFillStage(element, this._options, CanvasQuadraticPoint);
- case "bezierFill":
- return new SimpleCanvasPathFillStage(element, this._options, CanvasBezierPoint);
- case "arcToFill":
- return new SimpleCanvasStage(element, this._options, CanvasArcToSegmentFill);
- case "arcFill":
- return new SimpleCanvasStage(element, this._options, CanvasArcSegmentFill);
- case "rectFill":
- return new SimpleCanvasStage(element, this._options, CanvasRectFill);
+});
+
+CanvasLinePathStage = Utilities.createSubclass(SimpleCanvasPathStrokeStage,
+ function()
+ {
+ SimpleCanvasPathStrokeStage.call(this, CanvasLinePoint);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ SimpleCanvasPathStrokeStage.prototype.initialize.call(this, benchmark);
+ this.context.lineJoin = benchmark.options["lineJoin"] || "bevel";
}
-}
+});
-window.benchmarkClient.create = function(suite, test, options, progressBar) {
- return new CanvasPathBenchmark(suite, test, options, progressBar);
-}
+CanvasLineDashStage = Utilities.createSubclass(SimpleCanvasStage,
+ function()
+ {
+ SimpleCanvasStage.call(this, CanvasLinePoint);
+ this._step = 0;
+ }, {
+
+ initialize: function(benchmark)
+ {
+ SimpleCanvasStage.prototype.initialize.call(this, benchmark);
+ this.context.setLineDash([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+ this.context.lineWidth = 1;
+ this.context.strokeStyle = "#000";
+ },
+
+ animate: function()
+ {
+ var context = this.context;
+ context.clearRect(0, 0, this.size.x, this.size.y);
+ context.lineDashOffset = this._step++;
+ context.beginPath();
+ context.moveTo(0,0);
+ this.objects.forEach(function(object) {
+ object.draw(context);
+ });
+ context.stroke();
+ }
+});
+
+// === BENCHMARK ===
+
+CanvasPathBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ var stage;
+ switch (options["pathType"]) {
+ case "line":
+ stage = new CanvasLineSegmentStage();
+ break;
+ case "linePath": {
+ if ("lineJoin" in options)
+ stage = new CanvasLinePathStage();
+ if ("lineDash" in options)
+ stage = new CanvasLineDashStage();
+ break;
+ }
+ case "quadratic":
+ stage = new SimpleCanvasStage(CanvasQuadraticSegment);
+ break;
+ case "quadraticPath":
+ stage = new SimpleCanvasPathStrokeStage(CanvasQuadraticPoint);
+ break;
+ case "bezier":
+ stage = new SimpleCanvasStage(CanvasBezierSegment);
+ break;
+ case "bezierPath":
+ stage = new SimpleCanvasPathStrokeStage(CanvasBezierPoint);
+ break;
+ case "arcTo":
+ stage = new SimpleCanvasStage(CanvasArcToSegment);
+ break;
+ case "arc":
+ stage = new SimpleCanvasStage(CanvasArcSegment);
+ break;
+ case "rect":
+ stage = new SimpleCanvasStage(CanvasRect);
+ break;
+ case "lineFill":
+ stage = new SimpleCanvasPathFillStage(CanvasLinePoint);
+ break;
+ case "quadraticFill":
+ stage = new SimpleCanvasPathFillStage(CanvasQuadraticPoint);
+ break;
+ case "bezierFill":
+ stage = new SimpleCanvasPathFillStage(CanvasBezierPoint);
+ break;
+ case "arcToFill":
+ stage = new SimpleCanvasStage(CanvasArcToSegmentFill);
+ break;
+ case "arcFill":
+ stage = new SimpleCanvasStage(CanvasArcSegmentFill);
+ break;
+ case "rectFill":
+ stage = new SimpleCanvasStage(CanvasRectFill);
+ break;
+ }
+
+ Benchmark.call(this, stage, options);
+ }
+);
+
+window.benchmarkClass = CanvasPathBenchmark;
+
+})();
\ No newline at end of file
-
-function SimpleCanvasStage(element, options, canvasObject)
-{
- Stage.call(this, element, options);
- this.context = this.element.getContext("2d");
- this.canvasObject = canvasObject;
- this._objects = [];
-}
-SimpleCanvasStage.prototype = Object.create(Stage.prototype);
-SimpleCanvasStage.prototype.constructor = SimpleCanvasStage;
-SimpleCanvasStage.prototype.tune = function(count)
-{
- if (count == 0)
- return this._objects.length;
-
- if (count > 0) {
- // For path-based tests, use the object length as a maximum coordinate value
- // to make it easier to see what the test is doing
- var coordinateMaximum = Math.max(this._objects.length, 200);
- for (var i = 0; i < count; ++i) {
- this._objects.push(new this.canvasObject(this, coordinateMaximum));
+Utilities.extendObject(SimpleCanvasStage.prototype, {
+ tune: function(count)
+ {
+ if (count == 0)
+ return this.objects.length;
+
+ if (count > 0) {
+ // For path-based tests, use the object length as a maximum coordinate value
+ // to make it easier to see what the test is doing
+ var coordinateMaximum = Math.max(this.objects.length, 200);
+ for (var i = 0; i < count; ++i)
+ this.objects.push(new this._canvasObject(this, coordinateMaximum));
+ return this.objects.length;
}
- return this._objects.length;
- }
-
- count = Math.min(-count, this._objects.length);
- this._objects.splice(-count, count);
-
- return this._objects.length;
-}
-SimpleCanvasStage.prototype.animate = function()
-{
- var context = this.context;
- this._objects.forEach(function(object) {
- object.draw(context);
- });
-}
-
-function SimpleCanvasAnimator(benchmark, options)
-{
- StageAnimator.call(this, benchmark, options);
- this._context = benchmark._stage.context;
-}
-
-SimpleCanvasAnimator.prototype = Object.create(StageAnimator.prototype);
-SimpleCanvasAnimator.prototype.constructor = SimpleCanvasAnimator;
-SimpleCanvasAnimator.prototype.animate = function()
-{
- this._context.clearRect(0, 0, this._benchmark._stage.size.x, this._benchmark._stage.size.y);
- return StageAnimator.prototype.animate.call(this, this._options);
-}
-
-
-function SimpleCanvasBenchmark(suite, test, options, progressBar) {
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
-SimpleCanvasBenchmark.prototype = Object.create(StageBenchmark.prototype);
-SimpleCanvasBenchmark.prototype.constructor = SimpleCanvasBenchmark;
-SimpleCanvasBenchmark.prototype.createAnimator = function() {
- return new SimpleCanvasAnimator(this, this._options);
-}
+ count = Math.min(-count, this.objects.length);
+ this.objects.splice(-count, count);
+ return this.objects.length;
+ }
+});
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <canvas id="stage"></canvas>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
+ <script src="../master/resources/canvas-stage.js"></script>
<script src="resources/simple-canvas.js"></script>
<script src="resources/simple-canvas-paths.js"></script>
-</head>
-<body>
- <canvas id="stage"></canvas>
</body>
</html>
+(function() {
+
function TemplateCanvasObject(stage)
{
// For the canvas stage, most likely you will need to create your
// animated object since it's only draw time thing.
-
+
// Fill in your object data.
}
-TemplateCanvasObject.prototype._draw = function()
-{
- // Draw your object.
-}
+TemplateCanvasObject.prototype = {
+ _draw: function()
+ {
+ // Draw your object.
+ },
-TemplateCanvasObject.prototype.animate = function(timeDelta)
-{
- // Redraw the animated object. The last time this animated
- // item was drawn before 'timeDelta'.
-
- // Move your object.
-
- // Redraw your object.
- this._draw();
-}
+ animate: function(timeDelta)
+ {
+ // Redraw the animated object. The last time this animated
+ // item was drawn before 'timeDelta'.
-function TemplateCanvasStage(element, options)
-{
- Stage.call(this, element, options);
- this.context = this.element.getContext("2d");
+ // Move your object.
- // Define a collection for your objects.
-}
+ // Redraw your object.
+ this._draw();
+ }
+};
-TemplateCanvasStage.prototype = Object.create(Stage.prototype);
-TemplateCanvasStage.prototype.constructor = TemplateCanvasStage;
+TemplateCanvasStage = Utilities.createSubclass(Stage,
+ function()
+ {
+ Stage.call(this);
+ }, {
-TemplateCanvasStage.prototype.tune = function(count)
-{
- // If count is -ve, -count elements need to be removed form the
- // stage. If count is +ve, +count elements need to be added to
- // the stage.
-
- // Change objects in the stage.
-
- // Return the number of all the elements in the stage.
- // This number is recorded in the sampled data.
-
- // Return the count of the objects in the stage.
- return 0;
-}
+ initialize: function(benchmark)
+ {
+ Stage.prototype.initialize.call(this, benchmark);
+ this.context = this.element.getContext("2d");
-TemplateCanvasStage.prototype.animate = function(timeDelta)
-{
- // Animate the elements such that all of them are redrawn. Most
- // likely you will need to call TemplateCanvasObject.animate()
- // for all your animated objects here.
+ // Define a collection for your objects.
+ },
- // Loop through all your objects and ask them to animate.
-}
+ tune: function(count)
+ {
+ // If count is -ve, -count elements need to be removed form the
+ // stage. If count is +ve, +count elements need to be added to
+ // the stage.
-function TemplateCanvasAnimator(benchmark, options)
-{
- Animator.call(this, benchmark, options);
- this._context = benchmark._stage.context;
-}
-
-TemplateCanvasAnimator.prototype = Object.create(StageAnimator.prototype);
-TemplateCanvasAnimator.prototype.constructor = TemplateCanvasAnimator;
+ // Change objects in the stage.
-TemplateCanvasAnimator.prototype.animate = function()
-{
- // Most likely you will need to clear the canvas with every redraw.
- this._context.clearRect(0, 0, this._benchmark._stage.size.x, this._benchmark._stage.size.y);
+ // Return the number of all the elements in the stage.
+ // This number is recorded in the sampled data.
- // Draw scene stuff here if needed.
+ // Return the count of the objects in the stage.
+ return 0;
+ },
- return StageAnimator.prototype.animate.call(this);
-}
+ animate: function(timeDelta)
+ {
+ // Animate the elements such that all of them are redrawn. Most
+ // likely you will need to call TemplateCanvasObject.animate()
+ // for all your animated objects here.
-function TemplateCanvasBenchmark(suite, test, options, progressBar)
-{
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
+ // Most likely you will need to clear the canvas with every redraw.
+ this.context.clearRect(0, 0, this.size.x, this.size.y);
-TemplateCanvasBenchmark.prototype = Object.create(StageBenchmark.prototype);
-TemplateCanvasBenchmark.prototype.constructor = TemplateCanvasBenchmark;
+ // Loop through all your objects and ask them to animate.
+ }
+});
-TemplateCanvasBenchmark.prototype.createStage = function(element)
-{
- // Attach the stage to the benchmark.
- return new TemplateCanvasStage(element, this._options);
-}
+TemplateCanvasBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new TemplateCanvasStage(), options);
+ }
+);
-TemplateCanvasBenchmark.prototype.createAnimator = function()
-{
- // Attach the animator to the benchmark.
- return new TemplateCanvasAnimator(this, this._options);
-}
+window.benchmarkClass = TemplateCanvasBenchmark;
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- // This function is called from the test harness which starts the
- // test by creating your benchmark object.
- return new TemplateCanvasBenchmark(suite, test, options, progressBar);
-}
+})();
\ No newline at end of file
-function TemplateCssStage(element, options)
-{
- Stage.call(this, element, options);
-}
-
-TemplateCssStage.prototype = Object.create(Stage.prototype);
-TemplateCssStage.prototype.constructor = TemplateCssStage;
-
-TemplateCssStage.prototype.tune = function(count)
-{
- // If count is -ve, -count elements need to be removed form the
- // stage. If count is +ve, +count elements need to be added to
- // the stage.
-
- // Change objects in the stage.
-
- // Return the number of all the elements in the stage.
- // This number is recorded in the sampled data.
-
- // Return the count of the objects in the stage.
- return 0;
-}
-
-TemplateCssStage.prototype.animate = function(timeDelta)
-{
- // Animate the elements such that all of them are redrawn. You
- // may need to define your object so it keeps its animation data.
- // This object should encapsulate a corrosponding HTMLElement.
- // You may also define a method called animate() in this object
- // and just call this function here for all the elements.
-
- // Loop through all your objects and ask them to animate.
-}
-
-function TemplateCssBenchmark(suite, test, options, progressBar)
-{
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
-
-TemplateCssBenchmark.prototype = Object.create(StageBenchmark.prototype);
-TemplateCssBenchmark.prototype.constructor = TemplateCssBenchmark;
-
-TemplateCssBenchmark.prototype.createStage = function(element)
-{
- // You need to override this method such that your stage is hooked
- // up to the benchmark.
- return new TemplateCssStage(element, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- // This function is called from the test harness which starts the
- // test by creating your benchmark object.
- return new TemplateCssBenchmark(suite, test, options, progressBar);
-}
+(function() {
+
+TemplateCssStage = Utilities.createSubclass(Stage,
+ function()
+ {
+ Stage.call(this);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ Stage.prototype.initialize.call(this, benchmark);
+
+ // Do initialization here.
+ },
+
+ tune: function(count)
+ {
+ // If count is -ve, -count elements need to be removed form the
+ // stage. If count is +ve, +count elements need to be added to
+ // the stage.
+
+ // Change objects in the stage.
+
+ // Return the number of all the elements in the stage.
+ // This number is recorded in the sampled data.
+
+ // Return the count of the objects in the stage.
+ return 0;
+ },
+
+ animate: function(timeDelta)
+ {
+ // Animate the elements such that all of them are redrawn. You
+ // may need to define your object so it keeps its animation data.
+ // This object should encapsulate a corrosponding HTMLElement.
+ // You may also define a method called animate() in this object
+ // and just call this function here for all the elements.
+
+ // Loop through all your objects and ask them to animate.
+ }
+});
+
+TemplateCssBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new TemplateCssStage(), options);
+ }
+);
+
+window.benchmarkClass = TemplateCssBenchmark;
+
+})();
-function TemplateSvgStage(element, options)
-{
- Stage.call(this, element, options);
-}
-
-TemplateSvgStage.prototype = Object.create(Stage.prototype);
-TemplateSvgStage.prototype.constructor = TemplateSvgStage;
-
-TemplateSvgStage.prototype.tune = function(count)
-{
- // If count is -ve, -count elements need to be removed form the
- // stage. If count is +ve, +count elements need to be added to
- // the stage.
-
- // TODO: Change objects in the stage.
-
- // Return the number of all the elements in the stage.
- // This number is recorded in the sampled data.
-
- // TODO: Return the count of the objects in the stage.
- return 0;
-}
-
-TemplateSvgStage.prototype.animate = function(timeDelta)
-{
- // Animate the elements such that all of them are redrawn. You
- // may need to define your object so it keeps its animation data.
- // This object should encapsulate a corrosponding SVGElement.
- // You may also define a method called animate() in this object
- // and just call this function here for all the elements.
-
- // TODO: Loop through all your objects and ask them to animate.
-}
-
-function TemplateSvgBenchmark(suite, test, options, progressBar)
-{
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
-
-TemplateSvgBenchmark.prototype = Object.create(StageBenchmark.prototype);
-TemplateSvgBenchmark.prototype.constructor = TemplateSvgBenchmark;
-
-TemplateSvgBenchmark.prototype.createStage = function(element)
-{
- // You need to override this method such that your stage is hooked
- // up to the benchmark.
- return new TemplateSvgStage(element, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- // This function is called from the test harness which starts the
- // test by creating your benchmark object.
- return new TemplateSvgBenchmark(suite, test, options, progressBar);
-}
+(function() {
+
+TemplateSvgStage = Utilities.createSubclass(Stage,
+ function()
+ {
+ Stage.call(this);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ Stage.prototype.initialize.call(this, benchmark);
+
+ // Do initialization here.
+ },
+
+ tune: function(count)
+ {
+ // If count is -ve, -count elements need to be removed form the
+ // stage. If count is +ve, +count elements need to be added to
+ // the stage.
+
+ // TODO: Change objects in the stage.
+
+ // Return the number of all the elements in the stage.
+ // This number is recorded in the sampled data.
+
+ // TODO: Return the count of the objects in the stage.
+ return 0;
+ },
+
+ animate: function(timeDelta)
+ {
+ // Animate the elements such that all of them are redrawn. You
+ // may need to define your object so it keeps its animation data.
+ // This object should encapsulate a corrosponding SVGElement.
+ // You may also define a method called animate() in this object
+ // and just call this function here for all the elements.
+
+ // TODO: Loop through all your objects and ask them to animate.
+ }
+});
+
+TemplateSvgBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new TemplateSvgStage(), options);
+ }
+);
+
+window.benchmarkClass = TemplateSvgBenchmark;
+
+})();
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <canvas id="stage"></canvas>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/template-canvas.js"></script>
-</head>
-<body>
- <canvas id="stage"></canvas>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <div id="stage"></div>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/template-css.js"></script>
-</head>
-<body>
- <div id="stage"></div>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+ <svg id="stage"></svg>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/template-svg.js"></script>
-</head>
-<body>
- <svg id="stage"></svg>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="../resources/stage.css">
<style>
.text-layer {
position: absolute;
font-size: 0.96em;
}
}
- </style>
- <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+ </style>
+</head>
+<body>
+ <div id="stage"></div>
<script src="../../resources/algorithm.js"></script>
<script src="../../resources/strings.js"></script>
<script src="../../resources/sampler.js"></script>
<script src="../../resources/extensions.js"></script>
<script src="../resources/math.js"></script>
<script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
<script src="resources/layering-text.js"></script>
-</head>
-<body>
- <div id="stage"></div>
</body>
</html>
-function LayeringTextStage(element, options)
-{
- Stage.call(this, element, options);
- this._textElementParent = this.element;
- this._textElements = [];
- this._textItemIndex = 0;
- this._colorIndex = 0;
- this._animateCounts = 0;
-}
-
-LayeringTextStage.textItems = [
- "<div class='text-layer'>",
- "<h2>Types of benchmarks</h2>",
- "<ol>",
- "<li>Real program",
- "<ul>",
- "<li>word processing software</li>",
- "<li>tool software of CAD</li>",
- "<li>user's application software (i.e.: MIS)</li>",
- "</ul>",
- "</li>",
- "<li>Kernel",
- "<ul>",
- "<li>contains key codes</li>",
- "<li>normally abstracted from actual program</li>",
- "<li>popular kernel: Livermore loop</li>",
- "<li>linpack benchmark (contains basic linear algebra subroutine written in FORTRAN language)</li>",
- "<li>results are represented in MFLOPS</li>",
- "</ul>",
- "</li>",
- "<li>Synthetic Benchmark",
- "<ul>",
- "<li>Procedure for programming synthetic benchmark:",
- "<ul>",
- "<li>take statistics of all types of operations from many application programs</li>",
- "<li>get proportion of each operation</li>",
- "<li>write program based on the proportion above</li>",
- "</ul>",
- "</li>",
- "<li>Types of Synthetic Benchmark are:",
- "<ul>",
- "<li>Whetstone</li>",
- "<li>Dhrystone</li>",
- "</ul>",
- "</li>",
- "<li>These were the first general purpose industry standard computer benchmarks. They do not necessarily obtain high scores on modern pipelined computers.</li>",
- "</ul>",
- "</li>",
- "<li>I/O benchmarks</li>",
- "<li>Database benchmarks: to measure the throughput and response times of database management systems (DBMS')</li>",
- "<li>Parallel benchmarks: used on machines with multiple cores, processors or systems consisting of multiple machines</li>",
- "</ol>",
- "<h2>Common benchmarks</h2>",
- "<ul>",
- "<li>Business Applications Performance Corporation (BAPCo)</li>",
- "<li>Embedded Microprocessor Benchmark Consortium (EEMBC)</li>",
- "<li>Standard Performance Evaluation Corporation (SPEC), in particular their SPECint and SPECfp</li>",
- "<li>Transaction Processing Performance Council (TPC)</li>",
- "<li>Coremark: Embedded computing benchmark</li>",
- "</ul>",
- "<h3>Open source benchmarks</h3>",
- "<ul>",
- "<li>AIM Multiuser Benchmark: composed of a list of tests that could be mixed to create a 'load mix' that would simulate a specific computer function on any UNIX-type OS.</li>",
- "<li>Bonnie++: filesystem and hard drive benchmark</li>",
- "<li>BRL-CAD: cross-platform architecture-agnostic benchmark suite based on multithreaded ray tracing performance; baselined against a VAX-11/780; and used since 1984 for evaluating relative CPU performance, compiler differences, optimization levels, coherency, architecture differences, and operating system differences.</li>",
- "</ul>",
- "</div>"
-];
-
-LayeringTextStage.parseTextItem = function(textItem)
-{
- var parseResult = {};
- parseResult.tagStart = textItem.match(/<(.*?)>/g)[0];
- var spaceIndex = parseResult.tagStart.indexOf(" ");
- parseResult.nodeName = parseResult.tagStart.substring(1, spaceIndex != -1 ? spaceIndex : parseResult.tagStart.length - 1);
- parseResult.args = spaceIndex != -1 ? Utilities.parseArguments(parseResult.tagStart.substring(spaceIndex + 1, parseResult.tagStart.length - 1)) : {};
- var tagEnd = "</" + parseResult.nodeName + ">";
- parseResult.tagEnd = textItem.endsWith(tagEnd) ? tagEnd : "";
- return parseResult;
-}
-
-LayeringTextStage.isOpeningTextItem = function(textItem)
-{
- return !LayeringTextStage.parseTextItem(textItem).tagEnd.length;
-}
-
-LayeringTextStage.isClosingTextItem = function(textItem)
-{
- return textItem.indexOf("/") == +1;
-}
-
-LayeringTextStage.textItemsFlags = LayeringTextStage.textItems.map(function(textItem)
-{
- var textItemFlags = {};
- textItemFlags.isOpening = LayeringTextStage.isOpeningTextItem(textItem);
- textItemFlags.isClosing = LayeringTextStage.isClosingTextItem(textItem);
- return textItemFlags;
-});
+(function() {
+
+LayeringTextStage = Utilities.createSubclass(Stage,
+ function()
+ {
+ Stage.call(this);
+ }, {
+
+ initialize: function(benchmark)
+ {
+ Stage.prototype.initialize.call(this, benchmark);
+ this._textElementParent = this.element;
+ this._textElements = [];
+ this._textItemIndex = 0;
+ this._colorIndex = 0;
+ this._animateCounts = 0;
+ },
+
+ _nextTextItem: function(textItemFlags)
+ {
+ var textItem = LayeringTextStage.textItems[this._textItemIndex];
+ Utilities.extendObject(textItemFlags, LayeringTextStage.textItemsFlags[this._textItemIndex]);
+ this._textItemIndex = (this._textItemIndex + 1) % LayeringTextStage.textItems.length;
+ return textItem;
+ },
+
+ _previousTextItem: function(textItemFlags)
+ {
+ this._textItemIndex = (this._textItemIndex + LayeringTextStage.textItems.length - 1) % LayeringTextStage.textItems.length;
+ Utilities.extendObject(textItemFlags, LayeringTextStage.textItemsFlags[this._textItemIndex]);
+ return LayeringTextStage.textItems[this._textItemIndex];
+ },
+
+ _pushTextElement: function()
+ {
+ var textItemFlags = {};
+ var textItem = this._nextTextItem(textItemFlags);
+ for ( ; textItemFlags.isClosing; textItem = this._nextTextItem(textItemFlags))
+ this._textElementParent = this._textElementParent.parentNode;
+
+ var parseResult = LayeringTextStage.parseTextItem(textItem);
+ textItem = textItem.substring(parseResult.tagStart.length, textItem.length - parseResult.tagEnd.length);
+
+ var textElement = document.createElement(parseResult.nodeName);
+
+ for (var attrname in parseResult.args)
+ textElement.setAttribute(attrname, parseResult.args[attrname]);
+
+ this._textElementParent.appendChild(textElement);
+
+ if (!parseResult.tagEnd.length)
+ this._textElementParent = textElement;
+
+ textElement.innerHTML = textItem;
+
+ this._textElements.push(textElement);
+ return this._textElements.length;
+ },
-LayeringTextStage.isColorableTextItem = function(textItemFlags)
-{
- return !(textItemFlags.isOpening || textItemFlags.isClosing);
-}
-
-LayeringTextStage.isInsertableTextItem = function(textItemFlags)
-{
- return !textItemFlags.isClosing;
-}
-
-LayeringTextStage.colorableTextItems = LayeringTextStage.textItemsFlags.filter(function(textItemFlags)
-{
- return LayeringTextStage.isColorableTextItem(textItemFlags);
-}).length;
-
-LayeringTextStage.insertableTextItems = LayeringTextStage.textItemsFlags.filter(function(textItemFlags)
-{
- return LayeringTextStage.isInsertableTextItem(textItemFlags);
-}).length;
-
-LayeringTextStage.colorIndexToTextElementIndex = function(colorIndex)
-{
- var textElementIndex = 0;
- var index = 0;
-
- for (var textItemIndex = 0; textItemIndex < LayeringTextStage.textItemsFlags.length; ++textItemIndex) {
- if (LayeringTextStage.isColorableTextItem(LayeringTextStage.textItemsFlags[textItemIndex])) {
- if (++index > colorIndex)
- break;
- }
- if (LayeringTextStage.isInsertableTextItem(LayeringTextStage.textItemsFlags[textItemIndex]))
- ++textElementIndex;
- }
-
- return textElementIndex;
-}
-
-LayeringTextStage.prototype = Object.create(Stage.prototype);
-LayeringTextStage.prototype.constructor = LayeringTextStage;
-
-LayeringTextStage.prototype._nextTextItem = function(textItemFlags)
-{
- var textItem = LayeringTextStage.textItems[this._textItemIndex];
- Utilities.extendObject(textItemFlags, LayeringTextStage.textItemsFlags[this._textItemIndex]);
- this._textItemIndex = (this._textItemIndex + 1) % LayeringTextStage.textItems.length;
- return textItem;
-}
-
-LayeringTextStage.prototype._previousTextItem = function(textItemFlags)
-{
- this._textItemIndex = (this._textItemIndex + LayeringTextStage.textItems.length - 1) % LayeringTextStage.textItems.length;
- Utilities.extendObject(textItemFlags, LayeringTextStage.textItemsFlags[this._textItemIndex]);
- return LayeringTextStage.textItems[this._textItemIndex];
-}
-
-LayeringTextStage.prototype._pushTextElement = function()
-{
- var textItemFlags = {};
- var textItem = this._nextTextItem(textItemFlags);
- for ( ; textItemFlags.isClosing; textItem = this._nextTextItem(textItemFlags))
- this._textElementParent = this._textElementParent.parentNode;
-
- var parseResult = LayeringTextStage.parseTextItem(textItem);
- textItem = textItem.substring(parseResult.tagStart.length, textItem.length - parseResult.tagEnd.length);
-
- var textElement = document.createElement(parseResult.nodeName);
-
- for (var attrname in parseResult.args)
- textElement.setAttribute(attrname, parseResult.args[attrname]);
-
- this._textElementParent.appendChild(textElement);
-
- if (!parseResult.tagEnd.length)
- this._textElementParent = textElement;
-
- textElement.innerHTML = textItem;
-
- this._textElements.push(textElement);
- return this._textElements.length;
-}
-
-LayeringTextStage.prototype._popTextElement = function()
-{
- var textItemFlags = {};
- var textItem = this._previousTextItem(textItemFlags);
- for ( ; textItemFlags.isClosing; textItem = this._previousTextItem(textItemFlags))
- this._textElementParent = this._textElementParent.lastChild;
-
- if (textItemFlags.isOpening)
- this._textElementParent = this._textElementParent.parentNode;
-
- this._textElements[this._textElements.length - 1].remove();
-
- this._textElements.pop();
- return this._textElements.length;
-}
-
-LayeringTextStage.prototype._colorTextItem = function(color)
-{
- var textElementIndex = LayeringTextStage.colorIndexToTextElementIndex(this._colorIndex);
- for ( ; textElementIndex < this._textElements.length; textElementIndex += LayeringTextStage.insertableTextItems)
- this._textElements[textElementIndex].style.backgroundColor = color;
-}
-
-LayeringTextStage.prototype.animate = function(timeDelta)
-{
- this._colorTextItem("transparent");
- this._colorIndex = (this._colorIndex + 1) % LayeringTextStage.colorableTextItems;
- this._colorTextItem("YellowGreen");
-
- var blackTextElements = Math.min(this._textElements.length, LayeringTextStage.insertableTextItems);
- var i = 0;
- for ( ; i < this._textElements.length - blackTextElements; ++i)
- this._textElements[i].style.color = (this._animateCounts & 1) ? "LightYellow" : "white";
-
- for ( ; i < this._textElements.length; ++i)
- this._textElements[i].style.color = "black";
-
- ++this._animateCounts;
-}
-
-LayeringTextStage.prototype.tune = function(count)
-{
- if (count == 0)
+ _popTextElement: function()
+ {
+ var textItemFlags = {};
+ var textItem = this._previousTextItem(textItemFlags);
+ for ( ; textItemFlags.isClosing; textItem = this._previousTextItem(textItemFlags))
+ this._textElementParent = this._textElementParent.lastChild;
+
+ if (textItemFlags.isOpening)
+ this._textElementParent = this._textElementParent.parentNode;
+
+ this._textElements[this._textElements.length - 1].remove();
+
+ this._textElements.pop();
return this._textElements.length;
+ },
+
+ _colorTextItem: function(color)
+ {
+ var textElementIndex = LayeringTextStage.colorIndexToTextElementIndex(this._colorIndex);
+ for ( ; textElementIndex < this._textElements.length; textElementIndex += LayeringTextStage.insertableTextItems)
+ this._textElements[textElementIndex].style.backgroundColor = color;
+ },
+
+ animate: function(timeDelta)
+ {
+ this._colorTextItem("transparent");
+ this._colorIndex = (this._colorIndex + 1) % LayeringTextStage.colorableTextItems;
+ this._colorTextItem("YellowGreen");
+
+ var blackTextElements = Math.min(this._textElements.length, LayeringTextStage.insertableTextItems);
+ var i = 0;
+ for ( ; i < this._textElements.length - blackTextElements; ++i)
+ this._textElements[i].style.color = (this._animateCounts & 1) ? "LightYellow" : "white";
+
+ for ( ; i < this._textElements.length; ++i)
+ this._textElements[i].style.color = "black";
+
+ ++this._animateCounts;
+ },
+
+ tune: function(count)
+ {
+ if (count == 0)
+ return this._textElements.length;
+
+ if (count > 0) {
+ for (var i = 0; i < count; ++i)
+ this._pushTextElement();
+ return this._textElements.length;
+ }
- if (count > 0) {
+ count = Math.min(-count, this._textElements.length);
for (var i = 0; i < count; ++i)
- this._pushTextElement();
+ this._popTextElement();
+
return this._textElements.length;
}
-
- count = Math.min(-count, this._textElements.length);
- for (var i = 0; i < count; ++i)
- this._popTextElement();
-
- return this._textElements.length;
-}
-
-function LayeringTextBenchmark(suite, test, options, progressBar)
-{
- StageBenchmark.call(this, suite, test, options, progressBar);
-}
-
-LayeringTextBenchmark.prototype = Object.create(StageBenchmark.prototype);
-LayeringTextBenchmark.prototype.constructor = LayeringTextBenchmark;
-
-LayeringTextBenchmark.prototype.createStage = function(element)
-{
- return new LayeringTextStage(element, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, progressBar)
-{
- return new LayeringTextBenchmark(suite, test, options, progressBar);
-}
+});
+
+Utilities.extendObject(LayeringTextStage, {
+ textItems: [
+ "<div class='text-layer'>",
+ "<h2>Types of benchmarks</h2>",
+ "<ol>",
+ "<li>Real program",
+ "<ul>",
+ "<li>word processing software</li>",
+ "<li>tool software of CAD</li>",
+ "<li>user's application software (i.e.: MIS)</li>",
+ "</ul>",
+ "</li>",
+ "<li>Kernel",
+ "<ul>",
+ "<li>contains key codes</li>",
+ "<li>normally abstracted from actual program</li>",
+ "<li>popular kernel: Livermore loop</li>",
+ "<li>linpack benchmark (contains basic linear algebra subroutine written in FORTRAN language)</li>",
+ "<li>results are represented in MFLOPS</li>",
+ "</ul>",
+ "</li>",
+ "<li>Synthetic Benchmark",
+ "<ul>",
+ "<li>Procedure for programming synthetic benchmark:",
+ "<ul>",
+ "<li>take statistics of all types of operations from many application programs</li>",
+ "<li>get proportion of each operation</li>",
+ "<li>write program based on the proportion above</li>",
+ "</ul>",
+ "</li>",
+ "<li>Types of Synthetic Benchmark are:",
+ "<ul>",
+ "<li>Whetstone</li>",
+ "<li>Dhrystone</li>",
+ "</ul>",
+ "</li>",
+ "<li>These were the first general purpose industry standard computer benchmarks. They do not necessarily obtain high scores on modern pipelined computers.</li>",
+ "</ul>",
+ "</li>",
+ "<li>I/O benchmarks</li>",
+ "<li>Database benchmarks: to measure the throughput and response times of database management systems (DBMS')</li>",
+ "<li>Parallel benchmarks: used on machines with multiple cores, processors or systems consisting of multiple machines</li>",
+ "</ol>",
+ "<h2>Common benchmarks</h2>",
+ "<ul>",
+ "<li>Business Applications Performance Corporation (BAPCo)</li>",
+ "<li>Embedded Microprocessor Benchmark Consortium (EEMBC)</li>",
+ "<li>Standard Performance Evaluation Corporation (SPEC), in particular their SPECint and SPECfp</li>",
+ "<li>Transaction Processing Performance Council (TPC)</li>",
+ "<li>Coremark: Embedded computing benchmark</li>",
+ "</ul>",
+ "<h3>Open source benchmarks</h3>",
+ "<ul>",
+ "<li>AIM Multiuser Benchmark: composed of a list of tests that could be mixed to create a 'load mix' that would simulate a specific computer function on any UNIX-type OS.</li>",
+ "<li>Bonnie++: filesystem and hard drive benchmark</li>",
+ "<li>BRL-CAD: cross-platform architecture-agnostic benchmark suite based on multithreaded ray tracing performance; baselined against a VAX-11/780; and used since 1984 for evaluating relative CPU performance, compiler differences, optimization levels, coherency, architecture differences, and operating system differences.</li>",
+ "</ul>",
+ "</div>"
+ ],
+
+ parseTextItem: function(textItem)
+ {
+ var parseResult = {};
+ parseResult.tagStart = textItem.match(/<(.*?)>/g)[0];
+ var spaceIndex = parseResult.tagStart.indexOf(" ");
+ parseResult.nodeName = parseResult.tagStart.substring(1, spaceIndex != -1 ? spaceIndex : parseResult.tagStart.length - 1);
+ parseResult.args = spaceIndex != -1 ? Utilities.parseArguments(parseResult.tagStart.substring(spaceIndex + 1, parseResult.tagStart.length - 1)) : {};
+ var tagEnd = "</" + parseResult.nodeName + ">";
+ parseResult.tagEnd = textItem.endsWith(tagEnd) ? tagEnd : "";
+ return parseResult;
+ },
+
+ isOpeningTextItem: function(textItem)
+ {
+ return !LayeringTextStage.parseTextItem(textItem).tagEnd.length;
+ },
+
+ isClosingTextItem: function(textItem)
+ {
+ return textItem.indexOf("/") == +1;
+ },
+
+ isColorableTextItem: function(textItemFlags)
+ {
+ return !(textItemFlags.isOpening || textItemFlags.isClosing);
+ },
+
+ isInsertableTextItem: function(textItemFlags)
+ {
+ return !textItemFlags.isClosing;
+ },
+
+ colorIndexToTextElementIndex: function(colorIndex)
+ {
+ var textElementIndex = 0;
+ var index = 0;
+
+ for (var textItemIndex = 0; textItemIndex < LayeringTextStage.textItemsFlags.length; ++textItemIndex) {
+ if (LayeringTextStage.isColorableTextItem(LayeringTextStage.textItemsFlags[textItemIndex])) {
+ if (++index > colorIndex)
+ break;
+ }
+ if (LayeringTextStage.isInsertableTextItem(LayeringTextStage.textItemsFlags[textItemIndex]))
+ ++textElementIndex;
+ }
+
+ return textElementIndex;
+ }
+});
+
+Utilities.extendObject(LayeringTextStage, {
+ textItemsFlags: LayeringTextStage.textItems.map(function(textItem)
+ {
+ var textItemFlags = {};
+ textItemFlags.isOpening = LayeringTextStage.isOpeningTextItem(textItem);
+ textItemFlags.isClosing = LayeringTextStage.isClosingTextItem(textItem);
+ return textItemFlags;
+ })
+});
+
+Utilities.extendObject(LayeringTextStage, {
+ colorableTextItems: LayeringTextStage.textItemsFlags.filter(function(textItemFlags)
+ {
+ return LayeringTextStage.isColorableTextItem(textItemFlags);
+ }).length,
+
+ insertableTextItems: LayeringTextStage.textItemsFlags.filter(function(textItemFlags)
+ {
+ return LayeringTextStage.isInsertableTextItem(textItemFlags);
+ }).length
+});
+
+LayeringTextBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new LayeringTextStage(), options);
+ }
+);
+
+window.benchmarkClass = LayeringTextBenchmark;
+
+})();
+
-function BouncingTextBox(stage, sampleText)
-{
- BouncingParticle.call(this, stage);
-
- this.element = document.createElement("div");
- this.element.classList.add('particle');
- this.element.style.width = this._size.x + "px";
- this.element.style.height = this._size.y + "px";
- this.element.textContent = sampleText;
-
- stage.element.appendChild(this.element);
- this._move();
-}
-
-BouncingTextBox.prototype = Object.create(BouncingParticle.prototype);
-BouncingTextBox.prototype.constructor = BouncingTextBox;
-
-BouncingTextBox.prototype._move = function()
-{
- this.element.style.left = this._position.x + "px";
- this.element.style.top = this._position.y + "px";
-}
-
-BouncingTextBox.prototype.animate = function(timeDelta)
-{
- BouncingParticle.prototype.animate.call(this, timeDelta);
- this._move();
-}
-
-function BouncingTextBoxStage(element, options)
-{
- BouncingParticlesStage.call(this, element, options);
- this._sampleText = document.getElementById('sample-text').textContent;
-}
-
-BouncingTextBoxStage.prototype = Object.create(BouncingParticlesStage.prototype);
-BouncingTextBoxStage.prototype.constructor = BouncingTextBoxStage;
-
-BouncingTextBoxStage.prototype.createParticle = function()
-{
- return new BouncingTextBox(this, this._sampleText);
-}
-
-BouncingTextBoxStage.prototype.particleWillBeRemoved = function(particle)
-{
- particle.element.remove();
-}
-
-function BouncingTextBoxsBenchmark(suite, test, options, recordTable, progressBar)
-{
- BouncingParticlesBenchmark.call(this, suite, test, options, recordTable, progressBar);
-}
-
-BouncingTextBoxsBenchmark.prototype = Object.create(BouncingParticlesBenchmark.prototype);
-BouncingTextBoxsBenchmark.prototype.constructor = BouncingTextBoxsBenchmark;
-
-BouncingTextBoxsBenchmark.prototype.createStage = function(element)
-{
- return new BouncingTextBoxStage(element, this._options);
-}
-
-window.benchmarkClient.create = function(suite, test, options, recordTable, progressBar)
-{
- return new BouncingTextBoxsBenchmark(suite, test, options, recordTable, progressBar);
-}
+(function() {
+
+BouncingTextBox = Utilities.createSubclass(BouncingParticle,
+ function(stage, sampleText)
+ {
+ BouncingParticle.call(this, stage);
+
+ this.element = document.createElement("div");
+ this.element.classList.add('particle');
+ this.element.style.width = this.size.x + "px";
+ this.element.style.height = this.size.y + "px";
+ this.element.textContent = sampleText;
+
+ stage.element.appendChild(this.element);
+ this._move();
+ }, {
+
+ _move: function()
+ {
+ this.element.style.left = this.position.x + "px";
+ this.element.style.top = this.position.y + "px";
+ },
+
+ animate: function(timeDelta)
+ {
+ BouncingParticle.prototype.animate.call(this, timeDelta);
+ this._move();
+ }
+});
+
+BouncingTextBoxStage = Utilities.createSubclass(BouncingParticlesStage,
+ function()
+ {
+ BouncingParticlesStage.call(this);
+ this._sampleText = document.getElementById('sample-text').textContent;
+ }, {
+
+ createParticle: function()
+ {
+ return new BouncingTextBox(this, this._sampleText);
+ },
+
+ particleWillBeRemoved: function(particle)
+ {
+ particle.element.remove();
+ }
+});
+
+BouncingTextBoxBenchmark = Utilities.createSubclass(Benchmark,
+ function(options)
+ {
+ Benchmark.call(this, new BouncingTextBoxStage(), options);
+ }
+);
+
+window.benchmarkClass = BouncingTextBoxBenchmark;
+
+})();
font-size: 0.96em;
}
}
-
+
.particle {
position: absolute;
width: 280px;
font-family: sans-serif;
padding: 3px;
}
-
+
#sample-text {
display: none;
}
- </style>
+ </style>
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
- <script src="../../resources/algorithm.js"></script>
- <script src="../../resources/strings.js"></script>
- <script src="../../resources/sampler.js"></script>
- <script src="../../resources/extensions.js"></script>
- <script src="../resources/math.js"></script>
- <script src="../resources/utilities.js"></script>
- <script src="../resources/main.js"></script>
- <script src="../resources/stage.js"></script>
- <script src="../bouncing-particles/resources/bouncing-particles.js"></script>
- <script charset="utf-8" src="resources/text-boxes.js"></script>
</head>
<body>
<div id="sample-text" class="particle">I can eat glass and it doesn't hurt me.
私はガラスを食べられます。それは私を傷つけません。
나는 유리를 먹을 수 있어요. 그래도 아프지 않아요
Я можу їсти скло, і воно мені не зашкодить.
- ನನಗೆ ಹಾನಿ ಆಗದೆ, ನಾನು ಗಜನ್ನು ತಿನಬಹುದು
+ ನನಗೆ ಹಾನಿ ಆಗದೆ, ನಾನು ಗಜನ್ನು ತಿನಬಹುದು
</div>
<div id="stage"></div>
+ <script src="../../resources/algorithm.js"></script>
+ <script src="../../resources/strings.js"></script>
+ <script src="../../resources/sampler.js"></script>
+ <script src="../../resources/extensions.js"></script>
+ <script src="../resources/math.js"></script>
+ <script src="../resources/main.js"></script>
+ <script src="../bouncing-particles/resources/bouncing-particles.js"></script>
+ <script charset="utf-8" src="resources/text-boxes.js"></script>
</body>
</html>
+2015-12-27 Jon Lee <jonlee@apple.com>
+
+ Simplify the test harness
+ https://bugs.webkit.org/show_bug.cgi?id=152562
+
+ Reviewed by Simon Fraser.
+
+ All of the benchmarks use the default Animator(). Don't require new tests
+ to pass a new instance, and instead just make one in the Benchmark constructor.
+
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-images.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-shapes.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-css-images.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-css-shapes.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js:
+ * Animometer/tests/master/resources/canvas-tests.js:
+ * Animometer/tests/misc/resources/canvas-electrons.js:
+ * Animometer/tests/misc/resources/canvas-stars.js:
+ * Animometer/tests/misc/resources/compositing-transforms.js:
+ * Animometer/tests/resources/main.js:
+ * Animometer/tests/simple/resources/simple-canvas-paths.js:
+ * Animometer/tests/template/resources/template-canvas.js:
+ * Animometer/tests/template/resources/template-css.js:
+ * Animometer/tests/template/resources/template-svg.js:
+ * Animometer/tests/text/resources/layering-text.js:
+ * Animometer/tests/text/resources/text-boxes.js:
+
+ Refactor the template.
+
+ * Animometer/tests/template/resources/template-canvas.js:
+ * Animometer/tests/template/resources/template-css.js:
+ * Animometer/tests/template/resources/template-svg.js:
+ * Animometer/tests/template/template-canvas.html:
+ * Animometer/tests/template/template-css.html:
+ * Animometer/tests/template/template-svg.html:
+
+ Refactor the SVG suite.
+
+ * Animometer/tests/bouncing-particles/bouncing-svg-images.html: Move scripts to the end.
+ * Animometer/tests/bouncing-particles/bouncing-svg-shapes.html: Ditto.
+
+ * Animometer/tests/bouncing-particles/bouncing-canvas-shapes.html: Remove extraneous includes
+ to stage.js.
+ * Animometer/tests/text/text-boxes.html: Ditto.
+
+ BouncingCanvasParticlesBenchmark is not necessary. Use Benchmark directly when subclassing.
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-particles.js: Remove
+ BouncingCanvasParticlesBenchmark.
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-images.js: Use Benchmark.
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-shapes.js: Ditto.
+
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js: Require the shape
+ in the constructor instead of having subclasses set the private variable.
+
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js: Refactor.
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js:
+
+ Refactor the HTML suite.
+
+ Move scripts to the end.
+ * Animometer/tests/bouncing-particles/bouncing-css-images.html:
+ * Animometer/tests/bouncing-particles/bouncing-css-shapes.html:
+ * Animometer/tests/text/layering-text.html:
+ * Animometer/tests/text/text-boxes.html:
+
+ Refactor to use the new variables.
+ * Animometer/tests/bouncing-particles/resources/bouncing-css-images.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-css-shapes.js:
+ * Animometer/tests/text/resources/layering-text.js:
+ * Animometer/tests/text/resources/text-boxes.js:
+
+ Refactor the bouncing canvas tests.
+
+ * Animometer/tests/bouncing-particles/bouncing-canvas-images.html: Move scripts to the end.
+ * Animometer/tests/bouncing-particles/bouncing-canvas-shapes.html: Move scripts to the end.
+
+ * Animometer/tests/bouncing-particles/resources/bouncing-particles.js: Promote a few
+ properties to "public" since they are used by subclasses.
+ (BouncingParticlesStage): Fix the constructor, which was missing "this". Make particles
+ "public" for subclasses.
+ (BouncingParticlesStage.initialize): Fix the max velocity, which was accidentally changed.
+ * Animometer/tests/misc/resources/compositing-transforms.js: Refactor.
+
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-particles.js:
+ BouncingCanvasParticlesAnimator is no longer needed.
+ (BouncingCanvasParticle): Change constructor to take a shape as a parameter instead of
+ having subclasses set the variable.
+
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-images.js: Refactor.
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-shapes.js: Refactor.
+
+ Move example/ files into misc/.
+
+ * Animometer/tests/misc/canvas-electrons.html: Renamed from PerformanceTests/Animometer/tests/examples/canvas-electrons.html.
+ * Animometer/tests/misc/canvas-stars.html: Renamed from PerformanceTests/Animometer/tests/examples/canvas-stars.html.
+ * Animometer/tests/misc/resources/canvas-electrons.js: Renamed from PerformanceTests/Animometer/tests/examples/resources/canvas-electrons.js.
+ * Animometer/tests/misc/resources/canvas-stars.js: Renamed from PerformanceTests/Animometer/tests/examples/resources/canvas-stars.js.
+
+ * Animometer/resources/debug-runner/tests.js: Update test URLs.
+
+ Refactor miscellaneous suite.
+
+ * Animometer/tests/bouncing-particles/resources/bouncing-particles.js:
+ Remove BouncingParticlesAnimator and BouncingParticleBenchmark, which are
+ not needed.
+ (tune): Remove console assert.
+ * Animometer/tests/resources/main.js: Add Rotater back in from stage.js.
+
+ * Animometer/tests/examples/resources/canvas-electrons.js: Remove CanvasElectronsAnimator.
+ * Animometer/tests/examples/resources/canvas-stars.js: Remove CanvasStarsAnimator.
+ * Animometer/tests/misc/resources/compositing-transforms.js:
+ * Animometer/tests/examples/canvas-electrons.html: Move scripts to the end.
+ * Animometer/tests/examples/canvas-stars.html: Ditto.
+ * Animometer/tests/misc/compositing-transforms.html: Ditto.
+
+ Refactor the simple suite.
+
+ * Animometer/tests/master/resources/canvas-stage.js:
+ (tune): Remove coordinateMaximum since it is not needed in any
+ of the master tests.
+ * Animometer/tests/simple/resources/simple-canvas.js:
+ SimpleCanvasAnimator and SimpleCanvasBenchmark are no longer
+ needed.
+ (tune): Manage the objects differently, but instead of duplicating
+ all of SimpleCanvasStage here, just replace tune(). Include
+ coordinateMaximum, and remove items from the end of the list
+ instead of the beginning.
+ (StageBenchmark.call.createAnimator): Deleted.
+ (StageBenchmark.call): Deleted.
+ * Animometer/tests/simple/resources/simple-canvas-paths.js:
+ * Animometer/tests/simple/simple-canvas-paths.html: Move
+ scripts to the end.
+
+ Get rid of stage.js, StageAnimator, and StageBenchmark. Don't have the progress bar update during the test.
+
+ * Animometer/resources/debug-runner/animometer.js:
+ (initialize): Move the setting of testsCount to the debug runner.
+ (didRunTest): Nicer name.
+ * Animometer/resources/debug-runner/benchmark-runner.js:
+ (BenchmarkRunner.prototype._runBenchmarkAndRecordResults): Don't pass in the progress bar to benchmarks.
+ * Animometer/resources/extensions.js:
+ (ProgressBar): Refactor. Make variables "private". Resetting the progress when instantiating.
+ (ProgressBar.prototype.incrementRange): This is called every time a benchmark completes.
+ * Animometer/resources/runner/animometer.js:
+ (window.benchmarkRunnerClient.initialize): Remove unneeded setting of testsCount.
+ * Animometer/resources/strings.js: These are no longer needed.
+ * Animometer/tests/master/canvas-stage.html: Remove script inclusion. Other tests will follow.
+ * Animometer/tests/master/resources/canvas-tests.js: Use Benchmark instead of StageBenchmark.
+ * Animometer/tests/resources/main.js: Messages are no longer needed
+ (Animator.prototype._shouldRequestAnotherFrame): Rename from animate(), since this method returns a boolean
+ indicating whether another frame should be requested. Collapse the logic from StageAnimator into animateLoop.
+ (BenchmarkState.prototype.currentStage): Deleted.
+ (BenchmarkState.prototype.currentMessage): Deleted.
+ (BenchmarkState.prototype.currentProgress): Deleted.
+ (Animator.prototype.animate): Deleted.
+ (Animator.prototype.animateLoop): The stage is animated only when we have another frame to draw.
+ (Benchmark.prototype.record): No need to update the progress bar.
+ * Animometer/tests/resources/stage.js: Removed. Rotater will appear in a later patch, in main.js.
+
+ * Animometer/resources/debug-runner/benchmark-runner.js:
+ (BenchmarkRunner.prototype._runBenchmarkAndRecordResults): Each test is run as a benchmark.
+ Remove the call to runBenchmark by merging the options here, and calling benchmark.run()
+ directly.
+
+ Make the class relationships more easily understandable. The benchmark owns the stage,
+ animator, and options. Make the stage and animator no longer have their own references to
+ the options. Make Stage a first-class citizen by promoting it to main.js. Later patches
+ will try to get rid of stage.js altogether.
+ * Animometer/tests/resources/main.js:
+ (Stage): Moved from stage.js.
+ (Animator): Don't pass in benchmark and options in its constructor. It will get initialized
+ by benchmark-related parameters in initialize().
+ (Animator.prototype.initialize): Add a back-reference to benchmark and cache an option.
+ (Animator.prototype.get benchmark):
+ (Animator.prototype.animate): Refactor to use the cached option, to remove its dependency on
+ the options dictionary.
+ (Benchmark): Require all benchmarks to have a stage and animator. The instance will initialize
+ them.
+ (Benchmark.prototype.get options):
+ (Benchmark.prototype.get stage): BenchmarkStates.stages will need to be renamed to avoid confusion.
+ (Benchmark.prototype.get animator):
+ (Benchmark.prototype.start):
+ (Benchmark.prototype.update): Ask the stage directly to tune or clear instead of adding another
+ level of indirection.
+ (window.runBenchmark): Deleted. Remove the need for a benchmarkClient. Also remove the standalone
+ path, since tests can be individually selected, and remove the need for runBenchmark since that is
+ handled in BenchmarkRunner._runBenchmarkAndRecordResults.
+ * Animometer/tests/resources/stage.js:
+ (Stage): Deleted. Moved to main.js.
+ (StageBenchmark): What's left is updating the progress bar; to be removed.
+ (StageAnimator): What's left can be folded in Animator.
+
+ Refactor master suite.
+ * Animometer/tests/master/resources/canvas-stage.js: This now only has SimpleCanvasStage.
+ (animate): Push the clearRect() into each stage.
+ (complexity):
+ (StageBenchmark.call.createAnimator): Deleted.
+ (StageBenchmark.call): Deleted.
+ * Animometer/tests/master/resources/canvas-tests.js: SimpleCanvasPathStrokeStage is no longer needed.
+ (CanvasLineSegment.prototype.draw):
+ (CanvasArc):
+ (CanvasLinePoint): Remove the draw call because depending on its index it either needs to be moveTo
+ or lineTo, and it is otherwise a very small draw operation that doesn't need the overhead of the
+ function call. Do all of the drawing through the stage.
+
+ Refactor the subclass pattern. Introduce Utilities.createSubclass().
+
+ * Animometer/resources/debug-runner/benchmark-runner.js:
+ * Animometer/resources/extensions.js:
+ (window.Utilities.createSubclass): Takes the super class, a function representing
+ the class's constructor, and additional methods to attach to the new class's
+ prototype object.
+ * Animometer/tests/text/text-boxes.html: Remove unneeded reference to utilities.js.
+
+ Refactor tests.
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-images.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-particles.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-canvas-shapes.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-css-images.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-css-shapes.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-particles.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js:
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js:
+ * Animometer/tests/examples/resources/canvas-electrons.js:
+ * Animometer/tests/examples/resources/canvas-stars.js:
+ * Animometer/tests/master/resources/canvas-stage.js:
+ * Animometer/tests/master/resources/canvas-tests.js:
+ * Animometer/tests/misc/resources/compositing-transforms.js:
+ * Animometer/tests/resources/stage.js:
+ * Animometer/tests/simple/resources/simple-canvas-paths.js:
+ * Animometer/tests/simple/resources/simple-canvas.js:
+ * Animometer/tests/template/resources/template-canvas.js:
+ * Animometer/tests/template/resources/template-css.js:
+ * Animometer/tests/template/resources/template-svg.js:
+ * Animometer/tests/text/resources/layering-text.js: Reorder some of the methods
+ and properties since they rely on each other.
+ * Animometer/tests/text/resources/text-boxes.js:
+
+ * Animometer/resources/debug-runner/animometer.js: Arrange calls
+ in the order they are evoked.
+ * Animometer/resources/debug-runner/benchmark-runner.js:
+ (BenchmarkRunnerState.prototype.next): Get rid of return value since
+ no caller to next() uses it.
+ (BenchmarkRunnerState.prototype.prepareCurrentTest): Refactor the
+ promise to resolve simply when onload() is called instead of
+ looking for #stage.
+ (BenchmarkRunner.prototype._runTestAndRecordResults): Suite.run
+ simply calls runBenchmark(). Call it directly rather than through
+ the Suite.
+ (BenchmarkRunner.prototype.step): Remove unused parameter in
+ resolve callback.
+ (BenchmarkRunner.prototype.runMultipleIterations): Use this instead
+ of self since it is outside of the closure which needed the self
+ variable.
+ (resolveIfReady): Deleted.
+ (BenchmarkRunner.prototype.waitForElement): Deleted.
+ * Animometer/resources/runner/tests.js: prepare() and run() are
+ no longer needed.
+ (Suite.prototype.prepare): Deleted.
+ (Suite.prototype.run): Deleted.
+ * Animometer/tests/master/canvas-stage.html: Move all scripts to
+ the end of the page.
+
2015-12-23 Simon Fraser <simon.fraser@apple.com>
Add an Animometer developer test which animates text-rich boxes