Diff
Modified: trunk/PerformanceTests/Animometer/resources/extensions.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/resources/extensions.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/resources/extensions.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -14,6 +14,11 @@
return new Point(radiuses.x * Math.cos(angle), radiuses.y * Math.sin(angle));
}
+Point.elementClientSize = function(element)
+{
+ return new Point(element.clientWidth, element.clientHeight);
+}
+
Point.prototype =
{
// Used when the point object is used as a size object.
@@ -65,12 +70,19 @@
Insets.prototype =
{
- get width() {
+ get width()
+ {
return this.left + this.right;
},
- get height() {
+ get height()
+ {
return this.top + this.bottom;
+ },
+
+ get size()
+ {
+ return new Point(this.width, this.height);
}
}
@@ -110,10 +122,51 @@
this._chainedPromise.resolve(result);
}
-function Options(testInterval, frameRate)
+window.DocumentExtension =
{
- this.testInterval = testInterval;
- this.frameRate = frameRate;
+ createElement : function(name, attrs, parentElement)
+ {
+ var element = document.createElement(name);
+
+ for (var key in attrs)
+ element.setAttribute(key, attrs[key]);
+
+ parentElement.appendChild(element);
+ return element;
+ },
+
+ createSvgElement: function(name, attrs, xlinkAttrs, parentElement)
+ {
+ const svgNamespace = "http://www.w3.org/2000/svg";
+ 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;
+ },
+
+ insertCssRuleAfter: function(newRule, referenceRule)
+ {
+ var styleSheets = document.styleSheets;
+
+ for (var i = 0; i < styleSheets.length; ++i) {
+ for (var j = 0; j < styleSheets[i].cssRules.length; ++j) {
+ if (styleSheets[i].cssRules[j].selectorText == referenceRule) {
+ styleSheets[i].insertRule(newRule, j + 1);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
}
function ProgressBar(element, ranges)
@@ -227,11 +280,11 @@
_showHeader: function(message)
{
- var row = document.createElement("tr");
+ var thead = DocumentExtension.createElement("thead", {}, this.element);
+ var row = DocumentExtension.createElement("tr", {}, thead);
var queue = [];
this._showHeaderRow(row, queue, this._headers, message);
- this.element.appendChild(row);
while (queue.length) {
var row = null;
@@ -246,14 +299,13 @@
}
if (!row)
- var row = document.createElement("tr");
+ row = DocumentExtension.createElement("tr", {}, thead);
this._showHeaderRow(row, queue, entry.headers, "");
entry.element.colSpan = entry.headers.length;
}
if (row) {
- this.element.appendChild(row);
entries.forEach(function(entry) {
++entry.rowSpan;
});
@@ -290,14 +342,14 @@
}
var td = document.createElement("td");
- var button = document.createElement("div");
+ var button = document.createElement("button");
button.className = "small-button";
button.addEventListener("click", function() {
var samples = data[Strings["JSON_GRAPH"][0]];
var samplingTimeOffset = data[Strings["JSON_GRAPH"][1]];
var axes = Strings["TEXT_EXPERIMENTS"];
- window.showTestGraph(testName, axes, samples, samplingTimeOffset);
+ benchmarkController.showTestGraph(testName, axes, samples, samplingTimeOffset);
});
button.textContent = Strings["TEXT_RESULTS"][1] + "...";
@@ -314,11 +366,11 @@
}
var td = document.createElement("td");
- var button = document.createElement("div");
+ var button = document.createElement("button");
button.className = "small-button";
button.addEventListener("click", function() {
- window.showTestJSON(testName, testResults);
+ benchmarkController.showTestJSON(testName, testResults);
});
button.textContent = Strings["TEXT_RESULTS"][2] + "...";
@@ -390,3 +442,4 @@
}, this);
}
}
+
Modified: trunk/PerformanceTests/Animometer/runner/animometer.html (191852 => 191853)
--- trunk/PerformanceTests/Animometer/runner/animometer.html 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/animometer.html 2015-11-01 08:26:46 UTC (rev 191853)
@@ -14,71 +14,85 @@
<body>
<main>
<section id="home" class="selected">
- <p>
- Animometer is a browser benchmark that measures the complexity of an animation for
- which a browser can achieve 50 FPS (frame per second). It uses adaptive animations
- to tune their complexities to stay close to 50 FPS.
- </p>
- <div class="options">
- <div id="suites" class="column">
- <p>
- <label><input type="checkbox" id="toggleTests"> Show individual tests</label>
- </p>
- Suites:<br>
- </div>
- <div>
- <label>Test interval: <input id="test-interval" type="number" value="30"> seconds</label><br>
- <label>Frame rate: <input id="frame-rate" type="number" value="50"> fps</label><br>
- <label><input id="estimated-frame-rate" type="checkbox" checked> Estimated Frame Rate</label><br>
- <label><input id="fix-test-complexity" type="checkbox"> Fix test complexity after warmup</label><br>
- <label><input id="show-running-results" type="checkbox"> Show running results</label>
- </div>
- </div>
- <div class="buttons">
- <button _onclick_="startTest()">Start Test</button>
- </div>
+ <header>
+ <h2>
+ Animometer is a browser benchmark that measures the complexity of an animation for
+ which a browser can achieve 50 FPS (frame per second). It uses adaptive animations
+ to tune their complexities to stay close to 50 FPS.
+ </h2>
+ </header>
+ <suites>
+ <h2>Suites:</h2>
+ <ul class="tree"></ul>
+ </suites>
+ <options>
+ <h2>Options:</h2>
+ <label>Test interval: <input id="test-interval" type="number" value="30"> seconds</label><br>
+ <label>Frame rate: <input id="frame-rate" type="number" value="50"> fps</label><br>
+ <label><input id="estimated-frame-rate" type="checkbox" checked> Estimated Frame Rate</label><br>
+ <label><input id="fix-test-complexity" type="checkbox"> Fix test complexity after warmup</label><br>
+ <label><input id="show-running-results" type="checkbox"> Show running results</label><br>
+ <label><input id="normalize-for-device-scale-factor" type="checkbox"> Normalize for device scale factor</label>
+ </options>
+ <footer>
+ <button class="large-button" _onclick_="benchmarkController.startTest()">Start Test</button>
+ </footer>
</section>
<section id="running">
- <div id="testContainer"></div>
+ <div id="running-test"></div>
<div id="progress">
<div id="progress-completed"></div>
</div>
<div id="record">
- <table class="record-table"></table>
+ <table class="results-table"></table>
</div>
</section>
<section id="results">
- <h1>Results:</h1>
- <table class="results-table"></table>
- <div class="buttons">
- <button _onclick_="showJson()">JSON</button>
- <button _onclick_="startTest()">Test Again</button>
- </div>
+ <header>
+ <h1>Results:</h1>
+ </header>
+ <data>
+ <table class="results-table"></table>
+ </data>
+ <footer>
+ <button class="large-button" _onclick_="benchmarkController.showJson()">JSON</button>
+ <button class="large-button" _onclick_="benchmarkController.startTest()">Test Again</button>
+ </footer>
</section>
<section id="json">
- <h1>JSON:</h1>
- <textarea class="results-json"></textarea>
- <div class="buttons">
- <button _onclick_="showResults()">Results</button>
- <button _onclick_="startTest()">Test Again</button>
- </div>
+ <header>
+ <h1>JSON:</h1>
+ </header>
+ <data>
+ <div class="results-json" contentEditable="true"></div>
+ </data>
+ <footer>
+ <button class="large-button" _onclick_="benchmarkController.showResults()">Results</button>
+ <button class="large-button" _onclick_="benchmarkController.startTest()">Test Again</button>
+ </footer>
</section>
+ <section id="test-json">
+ <header>
+ <h1>JSON:</h1>
+ </header>
+ <data>
+ <div class="results-json" contentEditable="true"></div>
+ </data>
+ <footer>
+ <button class="large-button" _onclick_="benchmarkController.showResults()">Results</button>
+ <button class="large-button" _onclick_="benchmarkController.startTest()">Test Again</button>
+ </footer>
+ </section>
<section id="test-graph">
- <h1>Graph:</h1>
- <div id="graphContainer"></div>
- <div class="buttons">
- <button _onclick_="showResults()">Results</button>
- <button _onclick_="startTest()">Test Again</button>
- </div>
+ <header>
+ <h1>Graph:</h1>
+ </header>
+ <data></data>
+ <footer>
+ <button class="large-button" _onclick_="benchmarkController.showResults()">Results</button>
+ <button class="large-button" _onclick_="benchmarkController.startTest()">Test Again</button>
+ </footer>
</section>
- <section id="test-json">
- <h1>JSON:</h1>
- <textarea class="results-json"></textarea>
- <div class="buttons">
- <button _onclick_="showResults()">Results</button>
- <button _onclick_="startTest()">Test Again</button>
- </div>
- </section>
</main>
</body>
</html>
Modified: trunk/PerformanceTests/Animometer/runner/resources/animometer.css (191852 => 191853)
--- trunk/PerformanceTests/Animometer/runner/resources/animometer.css 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/resources/animometer.css 2015-11-01 08:26:46 UTC (rev 191853)
@@ -1,3 +1,13 @@
+/* -------------------------------------------------------------------------- */
+/* HTML and Body */
+/* -------------------------------------------------------------------------- */
+
+html,body {
+ height: 100%;
+ margin: 0px;
+ padding: 0px;
+}
+
body {
background-color: rgb(96, 96, 96);
color: rgb(235, 235, 235);
@@ -4,252 +14,419 @@
font-family: "Helvetica Neue", Helvetica, Verdana, sans-serif;
}
-main {
- display: block;
- position: absolute;
- width: 800px;
- height: 600px;
- top: 50%;
- left: 50%;
- margin-top: -321px;
- margin-left: -421px;
- padding: 15px;
- border: 6px solid rgb(235, 235, 235);
- border-radius: 20px;
+/* -------------------------------------------------------------------------- */
+/* Buttons */
+/* -------------------------------------------------------------------------- */
+
+button {
+ -webkit-appearance: none;
+ -webkit-user-select: none;
+ background-color: transparent;
}
-iframe {
- width: 800px;
- height: 600px;
- border: 0px none;
- position: absolute;
+button.large-button {
+ border: 3px solid rgb(235, 235, 235);
+ border-radius: 10px;
+ min-width: 200px;
+ padding: .5em 2em;
+ margin: 0 1em;
+ font-size: 25px;
+ color: rgb(235, 235, 235);
}
-label, p {
- font-size: 16px;
- line-height: 21px;
+button.large-button:active {
+ background-color: rgb(235, 235, 235);
+ color: rgb(46, 51, 55);
+ border-color: rgb(235, 235, 235) !important;
}
-section {
- display: none;
+button.large-button:disabled {
+ background-color: rgb(96, 96, 96);
+ color: rgb(128, 128, 128);
}
-section > p {
- margin: 10px 20px;
+button.small-button {
+ border: 1px solid DarkCyan;
+ border-radius: 2px;
+ padding: 1px 4px;
+ margin: 0 4px;
+ font-size: 9px;
+ color: black;
}
-section#home > p {
- margin: 0 auto;
- width: 70%;
- text-align: center;
+button.small-button:active {
+ background-color: DarkCyan;
+ color: rgb(46, 51, 55);
+ border-color: DarkCyan !important;
}
-section#home > p:first-child {
- margin-top: 160px;
- text-align: center;
+/* -------------------------------------------------------------------------- */
+/* Tree */
+/* -------------------------------------------------------------------------- */
+
+.tree {
+ margin: 1em;
+ overflow-y: scroll;
+ height: 80%;
}
-section.selected {
+.tree .expand-button {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+}
+
+.tree .expand-button ~ ul {
+ display: none;
+}
+
+.tree .expand-button:checked ~ ul {
display: block;
}
-#testContainer {
- position: absolute;
- top: 15px;
- left: 15px;
- width: 800px;
- height: 600px;
+.tree ul {
+ list-style-type:none;
}
-section#running > #progress {
- position: absolute;
- bottom: -6px;
- left: 60px;
- right: 60px;
- height: 6px;
- background-color: rgb(128, 128, 128);
- border-left: 6px solid rgb(46, 51, 55);
- border-right: 6px solid rgb(46, 51, 55);
+.tree li {
+ position: relative;
+ padding: 0 0 1em 1em;
}
-section#running #progress-completed {
- position: absolute;
- top: 0;
- left: 0;
- height: 6px;
- width: 0;
- background-color: rgb(235, 235, 235);
+.tree ul li {
+ list-style:none;
+ padding: 1em 0 0 0em;
}
-section#running > #record {
- position: absolute;
- bottom: -130px;
- left: 0px;
- right: 0px;
- height: 75px;
- color: rgb(128, 128, 128);
- padding: 15px;
- border: 6px solid rgb(235, 235, 235);
- border-radius: 20px;
+.tree > li:last-child {
+ padding-bottom: 0;
}
-section#running > #record > table,
-section#results > table {
+.tree-label {
+ position: relative;
+ display: inline-block;
+}
+
+label.tree-label {
+ cursor: pointer;
+}
+
+label.tree-label:before {
+ background: black;
+ color: white;
+ position: relative;
+ z-index: 1;
+ float: left;
+ margin: 0 1em 0 -2.1em;
+ width: 1em;
+ height: 1em;
+ border-radius: 1em;
+ content: '+';
+ text-align: center;
+ line-height: .9em;
+}
+
+:checked ~ label.tree-label:before {
+ content: '\2013';
+}
+
+/* -------------------------------------------------------------------------- */
+/* Results Table */
+/* -------------------------------------------------------------------------- */
+
+table.results-table {
width: 100%;
+ border: 2px solid DarkCyan;
+ border-collapse: collapse;
}
-section#running > #record > table td, th,
-section#results > table td, th {
+.results-table th,
+.results-table td {
font-size: 11px;
- border: 1px solid #98bf21;
padding: 3px 4px 2px 4px;
}
-
-section#running > #record > table tr.alt, td
-section#results > table tr.alt, td {
- color: #000000;
- background-color: #EAF2D3;
+
+.results-table th {
+ background: DarkCyan;
+ border-left: 1px solid LightCyan;
+ border-right: 1px solid LightCyan;
+ border-top: 1px solid LightCyan;
}
-
-section#running > #record > table th,
-section#results > table th {
- background-color: #A7C942;
- text-align: center;
+
+.results-table td {
+ background: white;
+ border-bottom: none;
+ border-left: none;
+ border-right: 1px solid DarkCyan;
+ border-top: 1px solid DarkCyan;
+ color: black;
}
-section#test-json > textarea,
-section#json > textarea {
- width: 800px;
- height: 460px;
+/* -------------------------------------------------------------------------- */
+/* Results JSON */
+/* -------------------------------------------------------------------------- */
+
+div.results-json {
+ width: 100%;
background-color: rgb(128, 128, 128);
- border: 1px solid rgb(235, 235, 235);
- color: white;
+ color: rgb(235, 235, 235);
white-space: pre;
- overflow: scroll;
+ font-size: 12px;
}
-.options {
- margin:0 auto;
- margin-top: 30px;
- width: 600px;
- align: center;
+/* -------------------------------------------------------------------------- */
+/* Main Layout */
+/* -------------------------------------------------------------------------- */
+
+main {
+ width: 100%;
+ height: 100%;
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ align-items: center;
+ -webkit-justify-content: center;
+ -ms-flex-pack: center;
+ justify-content: center;
}
-.options p {
- margin-top: 0;
+section {
+ width: 800px;
+ height: 600px;
+ display: none;
+ padding: 10px;
+ border: 6px solid rgb(235, 235, 235);
+ border-radius: 20px;
}
-#suites ul {
- list-style-type: none;
- margin: 0;
- padding: 0;
+section.selected {
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
}
-#suites ul ul {
- padding-left: 1.5em;
- display: none;
+section > header,
+section > footer {
+ margin: 10px;
+ padding: 10px;
+ -webkit-flex: 0 1 100%;
+ -ms-flex: 0 1 100%;
+ flex: 0 1 100%;
+ max-height: 15%;
}
-#suites ul ul input, #suites ul ul label {
- font-size: .8em;
+section > footer {
+ text-align: center;
+ clear: both;
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ align-items: center;
+ -webkit-justify-content: center;
+ -ms-flex-pack: center;
+ justify-content: center;
}
-#suites.showTests ul ul {
- display: block;
+/* -------------------------------------------------------------------------- */
+/* Home Section */
+/* -------------------------------------------------------------------------- */
+
+section#home {
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-align-content: center;
+ -ms-flex-line-pack: center;
+ align-content: center;
}
-.column {
- width: 55%;
- float:left;
+section#home > suites,
+section#home > options {
+ padding: 10px;
+ margin: 10px;
+ height: 50%;
}
-input[type="number"] {
- width:50px;
+section#home > suites {
+ padding-left: 80px;
+ -webkit-flex: 0 1 40%;
+ -ms-flex: 0 1 40%;
+ flex: 0 1 40%;
}
-.buttons {
- margin-top: 10px;
+section#home > options {
+ -webkit-flex: 1 1 auto;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+}
+
+section#home > options > label {
+ margin: 2em;
+ line-height: 2;
+}
+
+section#home > header > h2 {
+ margin: 0 auto;
+ width: 70%;
text-align: center;
- clear: both;
}
-button {
- -webkit-appearance: none;
- border: 3px solid rgb(235, 235, 235);
- border-radius: 10px;
- min-width: 200px;
- padding: 5px 20px;
- margin: 0 40px;
- font-size: 25px;
- color: rgb(235, 235, 235);
- background-color: transparent;
+section#home > options > label > input[type="number"] {
+ width: 50px;
+}
- -webkit-user-select: none;
+/* -------------------------------------------------------------------------- */
+/* Running Section */
+/* -------------------------------------------------------------------------- */
+
+section#running {
+ position: relative;
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ align-items: center;
+ -webkit-justify-content: center;
+ -ms-flex-pack: center;
+ justify-content: center;
}
-button:active {
+section#running > #running-test {
+ width: 100%;
+ height: 100%;
+}
+
+section#running > #running-test > iframe {
+ width: 100%;
+ height: 100%;
+ border: 0px none;
+}
+
+section#running > #progress {
+ position: absolute;
+ bottom: -6px;
+ left: 60px;
+ right: 60px;
+ height: 6px;
+ background-color: rgb(128, 128, 128);
+ border-left: 6px solid rgb(46, 51, 55);
+ border-right: 6px solid rgb(46, 51, 55);
+}
+
+section#running > #progress > #progress-completed {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 6px;
+ width: 0;
background-color: rgb(235, 235, 235);
- color: rgb(46, 51, 55);
- border-color: rgb(235, 235, 235) !important;
}
-button:focus {
- outline: none;
- border-color: rgb(232, 79, 79);
+section#running > #record {
+ position: absolute;
+ bottom: -95px;
+ left: 0px;
+ right: 0px;
+ padding: 16px;
}
-.small-button {
- -webkit-appearance: none;
- border: 1px solid rgb(96, 96, 96);
- border-radius: 2px;
- padding: 1px 4px;
- margin: 0 4px;
- background-color: transparent;
- cursor: pointer;
- text-align: center;
- -webkit-user-select: none;
+/* -------------------------------------------------------------------------- */
+/* Results Section */
+/* -------------------------------------------------------------------------- */
+
+section#results,
+section#json,
+section#test-json,
+section#test-graph {
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-justify-content: space-between;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ -webkit-align-content: space-between;
+ -ms-flex-line-pack: justify;
+ align-content: space-between;
+ -webkit-align-items: flex-start;
+ -ms-flex-align: start;
+ align-items: flex-start;
}
-#graphContainer {
- font: 10px sans-serif;
- color: rgb(235, 235, 235);
+section#results > data,
+section#json > data,
+section#test-json > data,
+section#test-graph > data {
+ overflow-y: scroll;
+ height: 70%;
+ -webkit-flex: 0 1 100%;
+ -ms-flex: 0 1 100%;
+ flex: 0 1 100%;
+ -webkit-align-self: stretch;
+ -ms-flex-item-align: stretch;
+ align-self: stretch;
}
+/* -------------------------------------------------------------------------- */
+/* Graph Section */
+/* -------------------------------------------------------------------------- */
+
+section#test-graph > data {
+ font: 10px sans-serif;
+ color: rgb(235, 235, 235);
+}
+
+section#test-graph > data > svg {
+ fill: none;
+ shape-rendering: crispEdges;
+}
+
.axis path,
.axis line {
- fill: none;
- stroke: #999;
- shape-rendering: crispEdges;
+ fill: none;
+ stroke: #999999;
+ shape-rendering: crispEdges;
}
.left-samples {
- fill: none;
- stroke: #7ADD49;
- stroke-width: 1.5px;
+ stroke: #7ADD49;
+ stroke-width: 1.5px;
}
.right-samples {
- fill: none;
stroke: #FA4925;
stroke-width: 1.5px;
}
.sample-time {
- fill: none;
stroke: #5493D6;
- stroke-width: 1px;
}
.left-mean {
- fill: none;
stroke: #7ADD49;
- stroke-width: 1px;
opacity: .8;
}
.right-mean {
- fill: none;
stroke: #FA4925;
- stroke-width: 1px;
opacity: .8;
}
+
+/* -------------------------------------------------------------------------- */
+/* JSON Section */
+/* -------------------------------------------------------------------------- */
+
+section#json > data,
+section#test-json > data {
+ border: 1px solid rgb(235, 235, 235);
+ box-sizing: border-box;
+}
Modified: trunk/PerformanceTests/Animometer/runner/resources/animometer.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/runner/resources/animometer.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/resources/animometer.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -3,11 +3,17 @@
testsCount: null,
progressBar: null,
recordTable: null,
- options: { testInterval: 30000, frameRate: 50, estimatedFrameRate: true, fixTestComplexity : false },
+ options: null,
score: 0,
_resultsDashboard: null,
_resultsTable: null,
+ initialize: function(suites, options)
+ {
+ this.testsCount = this.iterationCount * suites.reduce(function (count, suite) { return count + suite.tests.length; }, 0);
+ this.options = options;
+ },
+
willAddTestFrame: function (frame)
{
var main = document.querySelector("main");
@@ -24,10 +30,10 @@
willStartFirstIteration: function ()
{
this._resultsDashboard = new ResultsDashboard();
- this._resultsTable = new ResultsTable(document.querySelector(".results-table"), Headers);
+ this._resultsTable = new ResultsTable(document.querySelector("section#results > data > table"), Headers);
this.progressBar = new ProgressBar(document.getElementById("progress-completed"), this.testsCount);
- this.recordTable = new ResultsTable(document.querySelector(".record-table"), Headers);
+ this.recordTable = new ResultsTable(document.querySelector("section#running > #record > table"), Headers);
},
didRunSuites: function (suitesSamplers)
@@ -38,226 +44,365 @@
didFinishLastIteration: function ()
{
var json = this._resultsDashboard.toJSON(true, true);
+ this.score = json[Strings["JSON_SCORE"]];
this._resultsTable.showIterations(json[Strings["JSON_RESULTS"][0]]);
-
- var element = document.querySelector("#json > textarea");
- element.innerHTML = JSON.stringify(json[Strings["JSON_RESULTS"][0]][0], function(key, value) {
- if (typeof value == "number")
- return value.toFixed(2);
- return value;
- }, 4);
-
- this.score = json[Strings["JSON_SCORE"]];
- showResults();
+ sectionsManager.showJSON("json", json[Strings["JSON_RESULTS"][0]][0]);
+ benchmarkController.showResults();
}
}
-function showSection(sectionIdentifier, pushState)
+window.sectionsManager =
{
- var currentSectionElement = document.querySelector("section.selected");
- console.assert(currentSectionElement);
+ _sectionHeaderH1Element: function(sectionIdentifier)
+ {
+ return document.querySelector("#" + sectionIdentifier + " > header > h1");
+ },
+
+ _sectionDataDivElement: function(sectionIdentifier)
+ {
+ return document.querySelector("#" + sectionIdentifier + " > data > div");
+ },
+
+ showScore: function(sectionIdentifier, title)
+ {
+ var element = this._sectionHeaderH1Element(sectionIdentifier);
+ element.textContent = title + ":";
- var newSectionElement = document.getElementById(sectionIdentifier);
- console.assert(newSectionElement);
+ var score = benchmarkRunnerClient.score.toFixed(2);
+ element.textContent += " [Score = " + score + "]";
+ },
+
+ showTestName: function(sectionIdentifier, title, testName)
+ {
+ var element = this._sectionHeaderH1Element(sectionIdentifier);
+ element.textContent = title + ":";
- currentSectionElement.classList.remove("selected");
- newSectionElement.classList.add("selected");
+ if (!testName.length)
+ return;
+
+ element.textContent += " [test = " + testName + "]";
+ },
+
+ showJSON: function(sectionIdentifier, json)
+ {
+ var element = this._sectionDataDivElement(sectionIdentifier);
+ element.textContent = JSON.stringify(json, function(key, value) {
+ if (typeof value == "number")
+ return value.toFixed(2);
+ return value;
+ }, 4);
+ },
+
+ showSection: function(sectionIdentifier, pushState)
+ {
+ var currentSectionElement = document.querySelector("section.selected");
+ console.assert(currentSectionElement);
- if (pushState)
- history.pushState({section: sectionIdentifier}, document.title);
-}
+ var newSectionElement = document.getElementById(sectionIdentifier);
+ console.assert(newSectionElement);
-function startBenchmark()
-{
- var enabledSuites = [];
+ currentSectionElement.classList.remove("selected");
+ newSectionElement.classList.add("selected");
- localStorage.clear();
- var suiteItems = document.querySelectorAll("#suites > ul > li");
- for (var i = 0; i < suiteItems.length; ++i) {
- var suiteItem = suiteItems[i];
- var suiteCheckbox = suiteItem.querySelector("input");
+ if (pushState)
+ history.pushState({section: sectionIdentifier}, document.title);
+ },
- if (!suiteCheckbox.checked)
- continue;
+ setupSectionStyle: function()
+ {
+ if (screen.width >= 1800 && screen.height >= 1000)
+ DocumentExtension.insertCssRuleAfter(" section { width: 1600px; height: 800px; }", "section");
+ else
+ DocumentExtension.insertCssRuleAfter(" section { width: 800px; height: 600px; }", "section");
+ },
+
+ setupRunningSectionStyle: function(options)
+ {
+ if (!options["show-running-results"])
+ document.getElementById("record").style.display = "none";
- var enabledTests = [];
- var testCheckboxes = suiteItem.querySelector("ul").querySelectorAll("input");
- for (var j = 0; j < testCheckboxes.length; ++j) {
- var testCheckbox = testCheckboxes[j];
- if (!testCheckbox.checked)
- continue;
-
- enabledTests.push(testCheckbox.test);
- localStorage.setItem(localStorageNameForTest(suiteCheckbox.suite, testCheckbox.test), +testCheckbox.checked);
+ if (options["normalize-for-device-scale-factor"] && window.devicePixelRatio != 1) {
+ var percentage = window.devicePixelRatio * 100;
+ var rule = "section#running > #running-test > iframe";
+ var newRule = rule;
+ newRule += " { ";
+ newRule += "width: " + percentage + "%; ";
+ newRule += "height: " + percentage + "%; ";
+ newRule += "transform: scale(" + 100 / percentage + ") translate(" + (100 - percentage) / 2 + "%," + (100 - percentage) / 2 + "%);";
+ newRule += " }";
+ DocumentExtension.insertCssRuleAfter(newRule, rule);
}
-
- enabledSuites.push(new Suite(suiteCheckbox.suite.name, enabledTests));
}
+}
- localStorage.setItem("test-interval", document.getElementById("test-interval").value);
-
- var testsCount = enabledSuites.reduce(function (testsCount, suite) { return testsCount + suite.tests.length; }, 0);
- benchmarkRunnerClient.testsCount = benchmarkRunnerClient.iterationCount * testsCount;
- benchmarkRunnerClient.options["testInterval"] = parseInt(document.getElementById("test-interval").value) * 1000;
- benchmarkRunnerClient.options["frameRate"] = parseInt(document.getElementById("frame-rate").value);
- benchmarkRunnerClient.options["estimatedFrameRate"] = document.getElementById("estimated-frame-rate").checked;
- benchmarkRunnerClient.options["fixTestComplexity"] = document.getElementById("fix-test-complexity").checked;
- benchmarkRunnerClient.options["showRunningResults"] = document.getElementById("show-running-results").checked;
+window.optionsManager =
+{
+ _optionsElements : function()
+ {
+ return document.querySelectorAll("section#home > options input");;
+ },
- if (!benchmarkRunnerClient.options["showRunningResults"])
- document.getElementById("record").style.display = "none";
+ updateUIFromLocalStorage: function()
+ {
+ var optionsElements = this._optionsElements();
- var runner = new BenchmarkRunner(enabledSuites, benchmarkRunnerClient);
- runner.runMultipleIterations(benchmarkRunnerClient.iterationCount);
-}
+ for (var i = 0; i < optionsElements.length; ++i) {
+ var optionElement = optionsElements[i];
+
+ var value = localStorage.getItem(optionElement.id);
+ if (value === null)
+ continue;
-function startTest()
-{
- showSection("running");
- startBenchmark();
-}
+ if (optionElement.getAttribute("type") == "number")
+ optionElement.value = +value;
+ else if (optionElement.getAttribute("type") == "checkbox")
+ optionElement.checked = value == "true";
+ }
+ },
-function showResults()
-{
- var element = document.querySelector("#results > h1");
- element.textContent = Strings["TEXT_RESULTS"][0] + ":";
+ updateLocalStorageFromUI: function()
+ {
+ var optionsElements = this._optionsElements();
+ var options = {};
+
+ for (var i = 0; i < optionsElements.length; ++i) {
+ var optionElement = optionsElements[i];
+
+ if (optionElement.getAttribute("type") == "number")
+ options[optionElement.id] = optionElement.value;
+ else if (optionElement.getAttribute("type") == "checkbox")
+ options[optionElement.id] = optionElement.checked;
- var score = benchmarkRunnerClient.score.toFixed(2);
- element.textContent += " [Score = " + score + "]";
+ localStorage.setItem(optionElement.id, options[optionElement.id]);
+ }
- showSection("results", true);
+ return options;
+ }
}
-function showJson()
+window.suitesManager =
{
- var element = document.querySelector("#json > h1");
- element.textContent = Strings["TEXT_RESULTS"][2] + ":";
+ _treeElement : function()
+ {
+ return document.querySelector("suites > .tree");
+ },
- var score = benchmarkRunnerClient.score.toFixed(2);
- element.textContent += " [Score = " + score + "]";
+ _suitesElements : function()
+ {
+ return document.querySelectorAll("#home > suites > ul > li");
+ },
+
+ _checkboxElement: function(element)
+ {
+ return element.querySelector("input[type='checkbox']:not(.expand-button)");
+ },
- showSection("json", true);
-}
+ _localStorageNameForTest: function(suite, test)
+ {
+ return suite.name + "/" + test.name;
+ },
-function showTestGraph(testName, axes, samples, samplingTimeOffset)
-{
- var element = document.querySelector("#test-graph > h1");
- element.textContent = Strings["TEXT_RESULTS"][1] + ":";
+ _updateSuiteCheckboxState: function(suiteCheckbox)
+ {
+ var numberEnabledTests = 0;
+ suiteCheckbox.testsElements.forEach(function(testElement) {
+ var testCheckbox = this._checkboxElement(testElement);
+ if (testCheckbox.checked)
+ ++numberEnabledTests;
+ }, this);
+ suiteCheckbox.checked = numberEnabledTests > 0;
+ suiteCheckbox.indeterminate = numberEnabledTests > 0 && numberEnabledTests < suiteCheckbox.testsElements.length;
+ },
- if (testName.length)
- element.textContent += " [test = " + testName + "]";
+ _updateStartButtonState: function()
+ {
+ var suitesElements = this._suitesElements();
+ var startButton = document.querySelector("#home > footer > button");
+
+ for (var i = 0; i < suitesElements.length; ++i) {
+ var suiteElement = suitesElements[i];
+ var suiteCheckbox = this._checkboxElement(suiteElement);
- graph("#graphContainer", new Point(700, 400), new Insets(20, 50, 20, 50), axes, samples, samplingTimeOffset);
- showSection("test-graph", true);
-}
+ if (suiteCheckbox.checked) {
+ startButton.disabled = false;
+ return;
+ }
+ }
+
+ startButton.disabled = true;
+ },
-function showTestJSON(testName, testResults)
-{
- var element = document.querySelector("#test-json > h1");
- element.textContent = Strings["TEXT_RESULTS"][2] + ":";
+ _onChangeSuiteCheckbox: function(event)
+ {
+ var selected = event.target.checked;
+ event.target.testsElements.forEach(function(testElement) {
+ var testCheckbox = this._checkboxElement(testElement);
+ testCheckbox.checked = selected;
+ }, this);
+ this._updateStartButtonState();
+ },
- if (testName.length)
- element.textContent += " [test = " + testName + "]";
-
- var element = document.querySelector("#test-json > textarea");
- element.innerHTML = JSON.stringify(testResults, function(key, value) {
- if (typeof value == "number")
- return value.toFixed(2);
- return value;
- }, 4);
+ _onChangeTestCheckbox: function(event)
+ {
+ var suiteCheckbox = event.target.suiteCheckbox;
+ this._updateSuiteCheckboxState(suiteCheckbox);
+ this._updateStartButtonState();
+ },
- showSection("test-json", true);
-}
+ _createSuiteElement: function(treeElement, suite, id)
+ {
+ var suiteElement = DocumentExtension.createElement("li", {}, treeElement);
+ var expand = DocumentExtension.createElement("input", { type: "checkbox", class: "expand-button", id: id }, suiteElement);
+ var label = DocumentExtension.createElement("label", { class: "tree-label", for: id }, suiteElement);
-function initialize() {
- populateSettings();
+ var suiteCheckbox = DocumentExtension.createElement("input", { type: "checkbox" }, label);
+ suiteCheckbox.suite = suite;
+ suiteCheckbox._onchange_ = this._onChangeSuiteCheckbox.bind(this);
+ suiteCheckbox.testsElements = [];
- var toggleTestsCheckbox = document.getElementById("toggleTests");
- toggleTestsCheckbox._onchange_ = function(event) {
- if (event.target.checked)
- document.getElementById("suites").classList.add("showTests");
- else
- document.getElementById("suites").classList.remove("showTests");
- };
-}
+ label.appendChild(document.createTextNode(" " + suite.name));
+ return suiteElement;
+ },
-function updateSuiteSelection(event) {
- var selected = event.target.checked;
- var testCheckboxes = event.target.parentNode.parentNode.querySelector("ul").querySelectorAll("input");
- for (var i = 0; i < testCheckboxes.length; ++i) {
- testCheckboxes[i].checked = selected;
- }
-}
+ _createTestElement: function(listElement, test, suiteCheckbox)
+ {
+ var testElement = DocumentExtension.createElement("li", {}, listElement);
+ var span = DocumentExtension.createElement("span", { class: "tree-label" }, testElement);
-function updateTestSelection(event) {
- var testsList = event.target.parentNode.parentNode.parentNode;
- var suiteCheckbox = testsList.parentNode.querySelector("label > input");
+ var testCheckbox = DocumentExtension.createElement("input", { type: "checkbox" }, span);
+ testCheckbox.test = test;
+ testCheckbox._onchange_ = this._onChangeTestCheckbox.bind(this);
+ testCheckbox.suiteCheckbox = suiteCheckbox;
- updateSuiteCheckbox(testsList, suiteCheckbox);
-}
+ suiteCheckbox.testsElements.push(testElement);
+ span.appendChild(document.createTextNode(" " + test.name));
+ return testElement;
+ },
-function updateSuiteCheckbox(testsList, suiteCheckbox) {
- var numberEnabledTests = 0;
- var testCheckboxes = testsList.querySelectorAll("input");
- var totalCheckboxes = testCheckboxes.length;
- for (var i = 0; i < totalCheckboxes; ++i) {
- if (testCheckboxes[i].checked)
- ++numberEnabledTests;
- }
- suiteCheckbox.checked = numberEnabledTests > 0;
- suiteCheckbox.indeterminate = numberEnabledTests > 0 && numberEnabledTests < totalCheckboxes;
-}
+ createElements: function()
+ {
+ var treeElement = this._treeElement();
-function localStorageNameForTest(suite, test) {
- return suite.name + "/" + test.name;
-}
+ Suites.forEach(function(suite, index) {
+ var suiteElement = this._createSuiteElement(treeElement, suite, "suite-" + index);
+ var listElement = DocumentExtension.createElement("ul", {}, suiteElement);
+ var suiteCheckbox = this._checkboxElement(suiteElement);
-function populateSettings() {
- var suitesDiv = document.getElementById("suites");
+ suite.tests.forEach(function(test) {
+ var testElement = this._createTestElement(listElement, test, suiteCheckbox);
+ }, this);
+ }, this);
+ },
+
+ 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 test = testCheckbox.test;
+
+ var str = localStorage.getItem(this._localStorageNameForTest(suite, test));
+ if (str === null)
+ return;
- var suitesList = document.createElement("ul");
- suitesDiv.appendChild(suitesList);
+ var value = JSON.parse(str);
+ testCheckbox.checked = value.checked;
+ }, this);
- Suites.forEach(function(suite) {
- var suiteItem = document.createElement("li");
- suitesList.appendChild(suiteItem);
+ this._updateSuiteCheckboxState(suiteCheckbox);
+ }
+
+ this._updateStartButtonState();
+ },
- var suiteLabel = document.createElement("label");
- suiteItem.appendChild(suiteLabel);
+ updateLocalStorageFromUI: function()
+ {
+ var suitesElements = this._suitesElements();
+ var suites = [];
+
+ for (var i = 0; i < suitesElements.length; ++i) {
+ var suiteElement = suitesElements[i];
+ var suiteCheckbox = this._checkboxElement(suiteElement);
+ var suite = suiteCheckbox.suite;
- var suiteCheckbox = document.createElement("input");
- suiteCheckbox.setAttribute("type", "checkbox");
- suiteCheckbox.suite = suite;
- suiteCheckbox._onchange_ = updateSuiteSelection;
- suiteLabel.appendChild(suiteCheckbox);
- suiteLabel.appendChild(document.createTextNode(" " + suite.name));
+ var tests = [];
+ suiteCheckbox.testsElements.forEach(function(testElement) {
+ var testCheckbox = this._checkboxElement(testElement);
+ var test = testCheckbox.test;
+
+ if (testCheckbox.checked)
+ tests.push(test);
- var testsList = document.createElement("ul");
- suiteItem.appendChild(testsList);
+ var value = { checked: testCheckbox.checked };
+ localStorage.setItem(this._localStorageNameForTest(suite, test), JSON.stringify(value));
+ }, this);
- suite.tests.forEach(function(test) {
- var testItem = document.createElement("li");
- testsList.appendChild(testItem);
+ if (tests.length)
+ suites.push(new Suite(suiteCheckbox.suite.name, tests));
+ }
- var testLabel = document.createElement("label");
- testItem.appendChild(testLabel);
+ return suites;
+ }
+}
- var testCheckbox = document.createElement("input");
- testCheckbox.setAttribute("type", "checkbox");
- testCheckbox.test = test;
- testCheckbox._onchange_ = updateTestSelection;
- if (+localStorage.getItem(localStorageNameForTest(suite, test)))
- testCheckbox.checked = true;
- testLabel.appendChild(testCheckbox);
- testLabel.appendChild(document.createTextNode(" " + test.name));
- });
+window.benchmarkController =
+{
+ initialize: function()
+ {
+ sectionsManager.setupSectionStyle();
+ optionsManager.updateUIFromLocalStorage();
+ suitesManager.createElements();
+ suitesManager.updateUIFromLocalStorage();
+ },
- updateSuiteCheckbox(testsList, suiteCheckbox);
- });
+ _runBenchmark: function(suites, options)
+ {
+ benchmarkRunnerClient.initialize(suites, options);
+ var frameContainer = document.querySelector("#running > #running-test");
+ var runner = new BenchmarkRunner(suites, frameContainer || document.body, benchmarkRunnerClient);
+ runner.runMultipleIterations();
+ },
- var interval = localStorage.getItem("test-interval");
- if (interval) {
- document.getElementById("test-interval").value = interval;
+ startTest: function()
+ {
+ var options = optionsManager.updateLocalStorageFromUI();
+ var suites = suitesManager.updateLocalStorageFromUI();
+ sectionsManager.setupRunningSectionStyle(options);
+ this._runBenchmark(suites, options);
+ sectionsManager.showSection("running");
+ },
+
+ showResults: function()
+ {
+ sectionsManager.showScore("results", Strings["TEXT_RESULTS"][0]);
+ sectionsManager.showSection("results", true);
+ },
+
+ showJson: function()
+ {
+ sectionsManager.showScore("json", Strings["TEXT_RESULTS"][0]);
+ sectionsManager.showSection("json", true);
+ },
+
+ showTestGraph: function(testName, axes, samples, samplingTimeOffset)
+ {
+ sectionsManager.showTestName("test-graph", Strings["TEXT_RESULTS"][1], testName);
+ sectionsManager.showSection("test-graph", true);
+ graph("section#test-graph > data", new Insets(20, 50, 20, 50), axes, samples, samplingTimeOffset);
+ },
+
+ showTestJSON: function(testName, json)
+ {
+ sectionsManager.showTestName("test-json", Strings["TEXT_RESULTS"][1], testName);
+ sectionsManager.showJSON("test-json", json);
+ sectionsManager.showSection("test-json", true);
}
}
-document.addEventListener("DOMContentLoaded", initialize);
+
+document.addEventListener("DOMContentLoaded", benchmarkController.initialize());
Modified: trunk/PerformanceTests/Animometer/runner/resources/benchmark-runner.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/runner/resources/benchmark-runner.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/resources/benchmark-runner.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -50,10 +50,11 @@
return promise;
}
-function BenchmarkRunner(suites, client)
+function BenchmarkRunner(suites, frameContainer, client)
{
this._suites = suites;
this._client = client;
+ this._frameContainer = frameContainer;
}
BenchmarkRunner.prototype.waitForElement = function(selector)
@@ -72,25 +73,15 @@
return promise;
}
-BenchmarkRunner.prototype._appendFrame = function(src)
+BenchmarkRunner.prototype._appendFrame = function()
{
var frame = document.createElement("iframe");
frame.setAttribute("scrolling", "no");
- var marginLeft = parseInt(getComputedStyle(document.body).marginLeft);
- var marginTop = parseInt(getComputedStyle(document.body).marginTop);
- if (window.innerWidth > 800 + marginLeft && window.innerHeight > 600 + marginTop) {
- frame.style.left = marginLeft + "px";
- frame.style.top = marginTop + "px";
- } else {
- frame.style.left = "0px";
- frame.style.top = "0px";
- }
-
if (this._client && this._client.willAddTestFrame)
this._client.willAddTestFrame(frame);
- document.body.insertBefore(frame, document.body.firstChild);
+ this._frameContainer.insertBefore(frame, this._frameContainer.firstChild);
this._frame = frame;
return frame;
}
@@ -167,21 +158,21 @@
});
}
-BenchmarkRunner.prototype.runMultipleIterations = function(iterationCount)
+BenchmarkRunner.prototype.runMultipleIterations = function()
{
var self = this;
var currentIteration = 0;
this._runNextIteration = function() {
currentIteration++;
- if (currentIteration < iterationCount)
+ 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(iterationCount);
+ self._client.willStartFirstIteration();
self.runAllSteps();
}
Modified: trunk/PerformanceTests/Animometer/runner/resources/graph.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/runner/resources/graph.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/resources/graph.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -1,8 +1,10 @@
-function graph(selector, size, margins, axes, samples, samplingTimeOffset)
+function graph(selector, margins, axes, samples, samplingTimeOffset)
{
var element = document.querySelector(selector);
- element.textContent = null;
+ element.innerHTML = '';
+ var size = Point.elementClientSize(element).subtract(margins.size);
+
var x = d3.scale.linear()
.range([0, size.width])
.domain(d3.extent(samples, function(d) { return d.timeOffset; }));
Modified: trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -5,7 +5,7 @@
var attrs = { x: 0, y: 0, width: this._size.x, height: this._size.y };
var xlinkAttrs = { href: stage.imageSrc };
- this.element = Utilities.createSvgElement("image", attrs, xlinkAttrs, stage.element);
+ this.element = DocumentExtension.createSvgElement("image", attrs, xlinkAttrs, stage.element);
this._move();
}
Modified: trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -39,7 +39,7 @@
BouncingSvgParticlesStage.prototype._createDefs = function()
{
- return Utilities.createSvgElement("defs", {}, {}, this.element);
+ return DocumentExtension.createSvgElement("defs", {}, {}, this.element);
}
BouncingSvgParticlesStage.prototype._ensureDefsIsCreated = function()
@@ -50,10 +50,10 @@
BouncingSvgParticlesStage.prototype._createClipStar = function()
{
var attrs = { id: "star-clip", clipPathUnits: "objectBoundingBox" };
- var clipPath = Utilities.createSvgElement("clipPath", attrs, {}, this._ensureDefsIsCreated());
+ 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" };
- Utilities.createSvgElement("path", attrs, {}, clipPath);
+ DocumentExtension.createSvgElement("path", attrs, {}, clipPath);
return clipPath;
}
Modified: trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -19,13 +19,13 @@
switch (this._shape) {
case "rect":
var attrs = { x: 0, y: 0, width: this._size.x, height: this._size.y };
- this.element = Utilities.createSvgElement("rect", attrs, {}, stage.element);
+ 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 = Utilities.createSvgElement("circle", attrs, {}, stage.element);
+ this.element = DocumentExtension.createSvgElement("circle", attrs, {}, stage.element);
break;
}
}
@@ -58,11 +58,11 @@
BouncingSvgShapesStage.prototype.createGradient = function(stops)
{
var attrs = { id: "gadient-" + ++this._gradientsCount };
- var gradient = Utilities.createSvgElement("linearGradient", attrs, {}, this._ensureDefsIsCreated());
+ var gradient = DocumentExtension.createSvgElement("linearGradient", attrs, {}, this._ensureDefsIsCreated());
for (var i = 0; i < stops; ++i) {
attrs = { offset: i * 100 / stops + "%", 'stop-color': this.randomColor() };
- Utilities.createSvgElement("stop", attrs, {}, gradient);
+ DocumentExtension.createSvgElement("stop", attrs, {}, gradient);
}
return gradient;
Modified: trunk/PerformanceTests/Animometer/tests/resources/main.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/tests/resources/main.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/resources/main.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -109,7 +109,7 @@
var currentFrameRate = Math.floor(1000 / (measureTimeDelta / this._measureFrameCount));
// Use Kalman filter to get a more non-fluctuating frame rate.
- if (this._benchmark.options.estimatedFrameRate)
+ if (this._benchmark.options["estimated-frame-rate"])
currentFrameRate = this._estimator.estimate(measureTimeDelta, currentFrameRate);
// Adjust the test to reach the desired FPS.
@@ -146,9 +146,9 @@
var lowValue = -parseInt(this._options["addLimit"]) || 1;
var highValue = parseInt(this._options["removeLimit"]) || 1;
- this._controller = new PIDController(gain, options.frameRate, lowValue, highValue);
+ this._controller = new PIDController(gain, options["frame-rate"], lowValue, highValue);
this._sampler = new Sampler(2);
- this._state = new BenchmarkState(this.options.testInterval);
+ this._state = new BenchmarkState(this.options["test-interval"] * 1000);
}
Benchmark.prototype =
@@ -179,7 +179,7 @@
}
var tuneValue = 0;
- if (!(this._isSampling && this.options.fixTestComplexity)) {
+ if (!(this._isSampling && this.options["fix-test-complexity"])) {
// The relationship between frameRate and test complexity is inverse-proportional so we
// need to use the negative of PIDController.tune() to change the complexity of the test.
tuneValue = -this._controller.tune(currentFrameRate, timeDelta / 1000);
Modified: trunk/PerformanceTests/Animometer/tests/resources/stage.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/tests/resources/stage.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/resources/stage.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -177,7 +177,7 @@
if (!this._recordTable || !this._progressBar || !this._test)
return;
- if (this.options.showRunningResults)
+ if (this.options["show-running-results"])
this._recordTable.showRecord(this._test.name, message, this._sampler.toJSON(true, false));
this._progressBar.setPos(progress);
Modified: trunk/PerformanceTests/Animometer/tests/resources/utilities.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/tests/resources/utilities.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/resources/utilities.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -39,22 +39,5 @@
mergeObjects: function(obj1, obj2)
{
return this.extendObject(this.copyObject(obj1), obj2);
- },
-
- createSvgElement: function(name, attrs, xlinkAttrs, parent)
- {
- const svgNamespace = "http://www.w3.org/2000/svg";
- 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]);
-
- parent.appendChild(element);
- return element;
}
}
Modified: trunk/PerformanceTests/Animometer/tests/text/layering-text.html (191852 => 191853)
--- trunk/PerformanceTests/Animometer/tests/text/layering-text.html 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/text/layering-text.html 2015-11-01 08:26:46 UTC (rev 191853)
@@ -3,12 +3,12 @@
<head>
<style>
.text-layer {
- font-size: 5.5px;
position: absolute;
left: 0px;
top: 0px;
padding: 3px;
background-color: transparent;
+ line-height: 1.2;
}
</style>
<link rel="stylesheet" type="text/css" href=""
Modified: trunk/PerformanceTests/Animometer/tests/text/resources/layering-text.js (191852 => 191853)
--- trunk/PerformanceTests/Animometer/tests/text/resources/layering-text.js 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/text/resources/layering-text.js 2015-11-01 08:26:46 UTC (rev 191853)
@@ -6,6 +6,7 @@
this._textItemIndex = 0;
this._colorIndex = 0;
this._animateCounts = 0;
+ this._setFontSize();
}
LayeringTextStage.textItems = [
@@ -137,6 +138,14 @@
LayeringTextStage.prototype = Object.create(Stage.prototype);
LayeringTextStage.prototype.constructor = LayeringTextStage;
+LayeringTextStage.prototype._setFontSize = function()
+{
+ var lineHeight = this.size.height / LayeringTextStage.colorableTextItems;
+ var fontHeight = lineHeight / 1.5;
+ var fontSize = fontHeight * 72.0 / 96.0;
+ DocumentExtension.insertCssRuleAfter(".text-layer", ".text-layer { font-size: " + fontSize.toFixed(2) + "px; }");
+}
+
LayeringTextStage.prototype._nextTextItem = function(textItemFlags)
{
var textItem = LayeringTextStage.textItems[this._textItemIndex];
Modified: trunk/PerformanceTests/ChangeLog (191852 => 191853)
--- trunk/PerformanceTests/ChangeLog 2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/ChangeLog 2015-11-01 08:26:46 UTC (rev 191853)
@@ -1,3 +1,226 @@
+2015-11-01 Said Abou-Hallawa <sabouhallawa@apple,com>
+
+ Make the size of the benchmark canvas adaptive to the screen size and screen resolution
+ https://bugs.webkit.org/show_bug.cgi?id=150530
+
+ Reviewed by Darin Adler.
+
+ We want to set the size of the benchmark stage dynamically such that it
+ depends on the screen resolution and the device scale factor. This patch
+ does more than that because the home page css was not done properly. To
+ use the flex box layout, the animometer.css has to be rewritten almost from
+ scratch. The suites tree has to be rewritten also because it was not collapsing
+ and with the flex box layout it was going outside of the window area. The
+ options handling and the local storage handling had to be rewritten to
+ allow more flexibility with this patch and the future patches. The code
+ in animometer.js was reorganized into objects to allow distributing the code
+ nicely among separate entities.
+
+ * Animometer/resources/extensions.js:
+ (Point.elementClientSize): Returns the client size of an HTMLElement as a Point object.
+ (Insets.prototype.get width): Follow the function opening brace style guidelines.
+ (Insets.prototype.get height):
+ (Insets.prototype.get size): Returns the size of an Insets as a Point object.
+
+ (window.DocumentExtension): Provides document helper functions. It should be assailable from the runner and the tests.
+ (window.DocumentExtension.createElement): Creates an HTMLElement given its name, attributes and parentElement.
+ (window.DocumentExtension.createSvgElement): Creates an SVGElement given its name, attributes and parentElement (moved from utilities.js).
+ (window.DocumentExtension.insertCssRuleAfter): Inserts a CSS rule after an exiting rule given its text.
+
+ (ResultsTable.prototype._showHeader): Use DocumentExtension functions.
+ (ResultsTable.prototype._showGraph): Use DocumentExtension functions and create a real button for "Graph..." option.
+ (ResultsTable.prototype._showJSON): Use DocumentExtension functions and create a real button for "JSON..." option.
+ (Options): Deleted.
+
+ * Animometer/runner/animometer.html: Restructure the page to use the flex box layout.
+
+ * Animometer/runner/resources/animometer.css:
+ (html,body):
+ (button):
+
+ (button.large-button):The large button appears in the animometer.html.
+ (button.large-button:active):
+ (button.large-button:disabled):
+
+ (button.small-button): The small button appears in the results table.
+ (button.small-button:active):
+
+ (.tree): The tree class is used to list the suites and their tests.
+ (.tree .expand-button): This button expands a tree element.
+ (.tree .expand-button ~ ul): Hide the children (<ul>...</ul>) of a parent node by default.
+ (.tree .expand-button:checked ~ ul): Show the children of a parent node only when checked.
+ (.tree ul): Hide the list bullets.
+ (.tree li): Indent every node in the tree relative to its parent.
+ (.tree ul li): Indent all the non top level nodes only (the tests nodes in our case).
+ (.tree > li:last-child): Do not indent the bottom of the last child node.
+ (.tree-label): Style for all the labels in the tree.
+ (label.tree-label): Style for the labels in the top level only (the suites nodes in our case).
+ (label.tree-label:before): Style the unchecked case of the expand-button.
+ (:checked ~ label.tree-label:before): Style the checked case of the expand-button.
+
+ (table.results-table): The results table appears while running the test and at the end.
+ (.results-table td):
+ (.results-table th):
+
+ (div.results-json): The JSON div appears per test or for the whole run.
+
+ (main): This is the flex box container.
+
+ (section): A section is displayed exclusively inside the <main>. It is hidden by default.
+ (section.selected): When it is selected, its layout is flex layout.
+ (section > footer): The header or the footer of a section should not take more than 15% of the container.
+
+ (section#home): The home section has <suites> and <options> parts to be laid out in the middle.
+ (section#home > options):
+ (section#home > suites): The <suites> should not take more than 40% of the width.
+ (section#home > options > label): The benchmark title.
+ (section#home > header > h2): The benchmark title.
+ (section#home > options > label > input[type="number"]): Sets the width of the option edit control.
+
+ (section#running): The running section contain the runner <iframe> which takes the whole area of the <main>.
+ (section#running > #running-test): This is the <iframe> container.
+ (section#running > #running-test > iframe): The <iframe> is created by the runner for each test.
+ (section#running > #progress): This is the progress bar.
+ (section#running > #progress > #progress-completed): This is another element which grows while the runner is progressing.
+ (section#running > #record): This the container of the record results table which is shown while running a test.
+
+ (section#results):
+ (section#json):
+ (section#test-json):
+ (section#test-graph): All these sections have the same layout. A <data> element is laid out between <header> and <footer>.
+
+ (section#results > data):
+ (section#json > data):
+ (section#test-json > data):
+ (section#test-graph > data): The <data> element should take 70% of the <section>.
+
+ (section#test-graph > data > svg):
+ (.axis line):
+ (.left-samples): These styles are for the d3 graph.
+
+ (section#test-json > data): This is the style of the JSON <data> element.
+
+ (iframe): Deleted.
+ (label, p): Deleted.
+ (section > p): Deleted.
+ (section#home > p): Deleted.
+ (section#home > p:first-child): Deleted.
+ (#testContainer): Deleted.
+ (section#running #progress-completed): Deleted.
+ (section#results > table): Deleted.
+ (section#results > table td, th): Deleted.
+ (section#results > table tr.alt, td): Deleted.
+ (section#results > table th): Deleted.
+ (section#json > textarea): Deleted.
+ (.options): Deleted.
+ (.options p): Deleted.
+ (#suites ul): Deleted.
+ (#suites ul ul): Deleted.
+ (#suites ul ul input, #suites ul ul label): Deleted.
+ (#suites.showTests ul ul): Deleted.
+ (.column): Deleted.
+ (input[type="number"]): Deleted.
+ (.buttons): Deleted.
+ (.small-button): Deleted.
+ (#graphContainer): Deleted.
+ (.right-samples): Deleted.
+ (.sample-time): Deleted.
+ (.left-mean): Deleted.
+ (.right-mean): Deleted.
+
+ * Animometer/runner/resources/animometer.js:
+ (window.benchmarkRunnerClient.initialize): Initialize the client object with the options and the suites.
+ (window.benchmarkRunnerClient.willStartFirstIteration): Use new css selectors for results and the record table.
+ (window.benchmarkRunnerClient.didFinishLastIteration): Move the code which sets the JSON text to sectionsManager.showJSON().
+
+ (window.sectionsManager): Responsible of managing the <section>s elements inside animometer.html.
+ (window.sectionsManager._sectionHeaderH1Element): Return the <h1> inside the <header> of a given section.
+ (window.sectionsManager._sectionDataDivElement): Return the <div> inside the <data> of a given section.
+ (window.sectionsManager.showScore): Show the score of the last benchmark run.
+ (window.sectionsManager.showTestName): Show the test name for detailed results <section>.
+ (window.sectionsManager.showJSON): Shows the JSON text of the last benchmark or for a specific test.
+ (window.sectionsManager.showSection): Shows a specific <section> in the <main> container.
+ (window.sectionsManager.setupSectionStyle): Sets css attributes for all the <section>s.
+ (window.sectionsManager.setupRunningSectionStyle): Sets the css attributes for the running <section> only.
+
+ (window.optionsManager): Responsible of managing the user options and streaming them to/form the localStorage.
+ (window.optionsManager._optionsElements): Returns the children <input> elements of the <options>.
+ (window.optionsManager.updateUIFromLocalStorage): Restore the values of the <options> UI elements from the local storage.
+ (window.optionsManager.updateLocalStorageFromUI): Saves the values of the <options> UI elements to the local storage.
+
+ (window.suitesManager): Responsible of managing the user suites and streaming them to/form the localStorage.
+ (window.suitesManager._treeElement): Returns the suites tree container element.
+ (window.suitesManager._suitesElements): Returns a list of the suites elements.
+ (window.suitesManager._checkboxElement): Returns the checkbox element of a given suite.
+ (window.suitesManager._localStorageNameForTest): Generates a string for the tuple <suite, test> to be saved in the localStorage.
+ (window.suitesManager._updateSuiteCheckboxState): Updates the state of a suite checkbox from the state of its tests' checkboxes.
+ (window.suitesManager._updateStartButtonState): Updates the state of the start button from the state of the suites' checkboxes.
+ (window.suitesManager._onChangeSuiteCheckbox): Called when a suite checkbox is clicked.
+ (window.suitesManager._onChangeTestCheckbox): Called when a test checkbox is clicked.
+ (window.suitesManager._createSuiteElement): Creates suite node in the suites tree.
+ (window.suitesManager._createTestElement): Creates test node in the suites tree.
+ (window.suitesManager.createElements): Creates the suites tree dynamically from the array Suites.
+ (window.suitesManager.updateUIFromLocalStorage): Restore the values of the <suites> UI elements from the local storage.
+ (window.suitesManager.updateLocalStorageFromUI): aves the values of the <suites> UI elements to the local storage.
+
+ (window.benchmarkController): This is the UI controller of the animometer.html page.
+ (window.benchmarkController.initialize): Called when the animometer.html page is loaded.
+ (window.benchmarkController._runBenchmark): Starts a benchmark run.
+ (window.benchmarkController.startTest): Called when the "Start Test" button is clicked.
+ (window.benchmarkController.showResults): Called at the end of the test to show the final results.
+ (window.benchmarkController.showJson): Called from the results page to show the JSON of the last benchmark run.
+ (window.benchmarkController.showTestGraph): Called from the results the table to show a graph for the samples of a specific test.
+ (window.benchmarkController.showTestJSON): Called from the results the table to show a JSON for the samples of a specific test.
+
+ (showSection): Deleted.
+ (startTest): Deleted.
+ (showResults): Deleted.
+ (showJson): Deleted.
+ (showTestGraph): Deleted.
+ (showTestJSON): Deleted.
+ (initialize.toggleTestsCheckbox.onchange): Deleted.
+ (initialize): Deleted.
+ (updateSuiteSelection): Deleted.
+ (updateTestSelection): Deleted.
+ (updateSuiteCheckbox): Deleted.
+ (localStorageNameForTest): Deleted.
+ (populateSettings.): Deleted.
+ (populateSettings): Deleted.
+
+ * Animometer/runner/resources/benchmark-runner.js:
+ (BenchmarkRunner): Pass the frameContainer element to the BenchmarkRunner.
+ (BenchmarkRunner.prototype._appendFrame): Remove unused parameter unwanted styling code.
+ (BenchmarkRunner.prototype.runMultipleIterations): Use the this._client.iterationCount instead of passing it as a parameter also.
+
+ * Animometer/runner/resources/graph.js:
+ (graph): Calculate the size of the chart from the container element.
+
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js:
+ (BouncingSvgImage):
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js:
+ (BouncingSvgParticlesStage.prototype._createDefs):
+ (BouncingSvgParticlesStage.prototype._createClipStar):
+ * Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js:
+ (BouncingSvgShape.prototype._createShape):
+ (BouncingSvgShapesStage.prototype.createGradient):
+ Call DocumentExtension.createSvgElement() instead of calling Utilities.createSvgElement().
+
+ * Animometer/tests/resources/main.js:
+ (Animator.prototype.animate):
+ (Benchmark):
+ (Benchmark.prototype.update):
+ * Animometer/tests/resources/stage.js:
+ (StageBenchmark.prototype.showResults):
+ Rename the options to match the <input> ids in animometer.html.
+
+ * Animometer/tests/resources/utilities.js:
+ (window.Utilities.createSvgElement): Deleted.
+
+ * Animometer/tests/text/layering-text.html:
+ * Animometer/tests/text/resources/layering-text.js:
+ (LayeringTextStage):
+ (LayeringTextStage.prototype._setFontSize): Sets the size of the text dynamically such that they all fit in one stage.
+
2015-10-29 Simon Fraser <[email protected]>
Animometer computes frame rate incorrectly