<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[191701] trunk/PerformanceTests</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/191701">191701</a></dd>
<dt>Author</dt> <dd>jonlee@apple.com</dd>
<dt>Date</dt> <dd>2015-10-28 16:11:37 -0700 (Wed, 28 Oct 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add an option to make the graphics benchmark runs a specific test
https://bugs.webkit.org/show_bug.cgi?id=150528
rdar://problem/23246614

Reviewed by Zalan Bujtas.

Add a checkbox that lets the user list all of the available tests, and select
the ones to run repeatedly. The test checkboxes will update the state of the suite
checkbox. The selected tests are stored in localStorage to make it easy to do
repeated runs.

* Animometer/runner/animometer.html: Add a checkbox to show individual tests.
Update other markup.
* Animometer/runner/resources/animometer.css: Make the settings area a little wider
to accommodate the longer names of the tests
* Animometer/runner/resources/animometer.js:
(startBenchmark): Change the way that the suites are fed into the benchmark
runner. Go through each of the suites and their tests, and create a new Suite
with just the enabled tests. While enumerating store the enabled tests into
localStorage.
(initialize): Initialization routine (taking over populateSettings). When the
checkbox for showing tests is toggled, add or remove a class on #suites to show
the individual tests.
(updateSuiteSelection): Called whenever the user toggles the checkbox for a suite.
Either select all or none of the tests.
(updateTestSelection): Called whenever the user toggles the checkbox for a test.
(updateSuiteCheckbox): Update the state of the test's suite's checkbox to
indeterminate if there is at least one enabled test, unchecked if none are selected,
and checked if all are selected.
(localStorageNameForTest): Helper function to get the name of the test to use as
a key to localStorage.
(populateSettings): Add the tests for each suite into an inner list.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsAnimometerrunneranimometerhtml">trunk/PerformanceTests/Animometer/runner/animometer.html</a></li>
<li><a href="#trunkPerformanceTestsAnimometerrunnerresourcesanimometercss">trunk/PerformanceTests/Animometer/runner/resources/animometer.css</a></li>
<li><a href="#trunkPerformanceTestsAnimometerrunnerresourcesanimometerjs">trunk/PerformanceTests/Animometer/runner/resources/animometer.js</a></li>
<li><a href="#trunkPerformanceTestsChangeLog">trunk/PerformanceTests/ChangeLog</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkPerformanceTestsAnimometerrunneranimometerhtml"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/runner/animometer.html (191700 => 191701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/runner/animometer.html        2015-10-28 22:59:03 UTC (rev 191700)
+++ trunk/PerformanceTests/Animometer/runner/animometer.html        2015-10-28 23:11:37 UTC (rev 191701)
</span><span class="lines">@@ -21,12 +21,16 @@
</span><span class="cx">             &lt;/p&gt;
</span><span class="cx">             &lt;div class=&quot;options&quot;&gt;
</span><span class="cx">                 &lt;div id=&quot;suites&quot; class=&quot;column&quot;&gt;
</span><ins>+                &lt;p&gt;
+                    &lt;label&gt;&lt;input type=&quot;checkbox&quot; id=&quot;toggleTests&quot;&gt; Show individual tests&lt;/label&gt;
+                &lt;/p&gt;
+                Suites:&lt;br&gt;
</ins><span class="cx">                 &lt;/div&gt;
</span><span class="cx">                 &lt;div&gt;
</span><span class="cx">                     &lt;label&gt;Test interval: &lt;input id=&quot;test-interval&quot; type=&quot;number&quot; value=&quot;30&quot;&gt; seconds&lt;/label&gt;&lt;br&gt;
</span><span class="cx">                     &lt;label&gt;Frame rate: &lt;input id=&quot;frame-rate&quot; type=&quot;number&quot; value=&quot;50&quot;&gt; fps&lt;/label&gt;&lt;br&gt;
</span><span class="cx">                     &lt;label&gt;&lt;input id=&quot;estimated-frame-rate&quot; type=&quot;checkbox&quot; checked&gt; Estimated Frame Rate&lt;/label&gt;&lt;br&gt;
</span><del>-                    &lt;label&gt;&lt;input id=&quot;fix-test-complexity&quot; type=&quot;checkbox&quot;&gt; Fix test complexity after warmup&lt;/label&gt;
</del><ins>+                    &lt;label&gt;&lt;input id=&quot;fix-test-complexity&quot; type=&quot;checkbox&quot;&gt; Fix test complexity after warmup&lt;/label&gt;&lt;br&gt;
</ins><span class="cx">                     &lt;label&gt;&lt;input id=&quot;show-running-results&quot; type=&quot;checkbox&quot;&gt; Show running results&lt;/label&gt;
</span><span class="cx">                 &lt;/div&gt;
</span><span class="cx">             &lt;/div&gt;
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometerrunnerresourcesanimometercss"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/runner/resources/animometer.css (191700 => 191701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/runner/resources/animometer.css        2015-10-28 22:59:03 UTC (rev 191700)
+++ trunk/PerformanceTests/Animometer/runner/resources/animometer.css        2015-10-28 23:11:37 UTC (rev 191701)
</span><span class="lines">@@ -131,15 +131,36 @@
</span><span class="cx"> .options {
</span><span class="cx">     margin:0 auto;    
</span><span class="cx">     margin-top: 30px;
</span><del>-    width: 500px;
</del><ins>+    width: 600px;
</ins><span class="cx">     align: center;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+.options p {
+    margin-top: 0;
+}
+
+#suites ul {
+    list-style-type: none;
+    margin: 0;
+    padding: 0;
+}
+
+#suites ul ul {
+    padding-left: 1.5em;
+    display: none;
+}
+
+#suites ul ul input, #suites ul ul label {
+    font-size: .8em;
+}
+
+#suites.showTests ul ul {
+    display: block;
+}
+
</ins><span class="cx"> .column {
</span><del>-    width: 45%;
</del><ins>+    width: 55%;
</ins><span class="cx">     float:left;
</span><del>-    height: 120px;
-    padding:5px;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> input[type=&quot;number&quot;] {
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometerrunnerresourcesanimometerjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/runner/resources/animometer.js (191700 => 191701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/runner/resources/animometer.js        2015-10-28 22:59:03 UTC (rev 191700)
+++ trunk/PerformanceTests/Animometer/runner/resources/animometer.js        2015-10-28 23:11:37 UTC (rev 191701)
</span><span class="lines">@@ -70,17 +70,32 @@
</span><span class="cx"> function startBenchmark()
</span><span class="cx"> {
</span><span class="cx">     var enabledSuites = [];
</span><del>-    var checkboxes = document.querySelectorAll(&quot;#suites input&quot;);
-    for (var i = 0; i &lt; checkboxes.length; ++i) {
-        var checkbox = checkboxes[i];
-        if (checkbox.checked) {
-            enabledSuites.push(checkbox.suite);
</del><ins>+
+    localStorage.clear();
+    var suiteItems = document.querySelectorAll(&quot;#suites &gt; ul &gt; li&quot;);
+    for (var i = 0; i &lt; suiteItems.length; ++i) {
+        var suiteItem = suiteItems[i];
+        var suiteCheckbox = suiteItem.querySelector(&quot;input&quot;);
+
+        if (!suiteCheckbox.checked)
+            continue;
+
+        var enabledTests = [];
+        var testCheckboxes = suiteItem.querySelector(&quot;ul&quot;).querySelectorAll(&quot;input&quot;);
+        for (var j = 0; j &lt; testCheckboxes.length; ++j) {
+            var testCheckbox = testCheckboxes[j];
+            if (!testCheckbox.checked)
+                continue;
+
+            enabledTests.push(testCheckbox.test);
+            localStorage.setItem(localStorageNameForTest(suiteCheckbox.suite, testCheckbox.test), +testCheckbox.checked);
</ins><span class="cx">         }
</span><del>-        localStorage.setItem(checkbox.suite.name, +checkbox.checked);
-        localStorage.setItem(&quot;test-interval&quot;, document.getElementById(&quot;test-interval&quot;).value);
</del><ins>+
+        enabledSuites.push(new Suite(suiteCheckbox.suite.name, enabledTests));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    var enabledSuites = Suites.filter(function (suite, index) { return !suite.disabled &amp;&amp; checkboxes[index].checked; });
</del><ins>+    localStorage.setItem(&quot;test-interval&quot;, document.getElementById(&quot;test-interval&quot;).value);
+
</ins><span class="cx">     var testsCount = enabledSuites.reduce(function (testsCount, suite) { return testsCount + suite.tests.length; }, 0);
</span><span class="cx">     benchmarkRunnerClient.testsCount = benchmarkRunnerClient.iterationCount * testsCount;
</span><span class="cx">     benchmarkRunnerClient.options[&quot;testInterval&quot;] = parseInt(document.getElementById(&quot;test-interval&quot;).value) * 1000;
</span><span class="lines">@@ -154,24 +169,90 @@
</span><span class="cx">     showSection(&quot;test-json&quot;, true);    
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function initialize() {
+    populateSettings();
+
+    var toggleTestsCheckbox = document.getElementById(&quot;toggleTests&quot;);
+    toggleTestsCheckbox.onchange = function(event) {
+        if (event.target.checked)
+            document.getElementById(&quot;suites&quot;).classList.add(&quot;showTests&quot;);
+        else
+            document.getElementById(&quot;suites&quot;).classList.remove(&quot;showTests&quot;);
+    };
+}
+
+function updateSuiteSelection(event) {
+    var selected = event.target.checked;
+    var testCheckboxes = event.target.parentNode.parentNode.querySelector(&quot;ul&quot;).querySelectorAll(&quot;input&quot;);
+    for (var i = 0; i &lt; testCheckboxes.length; ++i) {
+        testCheckboxes[i].checked = selected;
+    }
+}
+
+function updateTestSelection(event) {
+    var testsList = event.target.parentNode.parentNode.parentNode;
+    var suiteCheckbox = testsList.parentNode.querySelector(&quot;label &gt; input&quot;);
+
+    updateSuiteCheckbox(testsList, suiteCheckbox);
+}
+
+function updateSuiteCheckbox(testsList, suiteCheckbox) {
+    var numberEnabledTests = 0;
+    var testCheckboxes = testsList.querySelectorAll(&quot;input&quot;);
+    var totalCheckboxes = testCheckboxes.length;
+    for (var i = 0; i &lt; totalCheckboxes; ++i) {
+        if (testCheckboxes[i].checked)
+            ++numberEnabledTests;
+    }
+    suiteCheckbox.checked = numberEnabledTests &gt; 0;
+    suiteCheckbox.indeterminate = numberEnabledTests &gt; 0 &amp;&amp; numberEnabledTests &lt; totalCheckboxes;
+}
+
+function localStorageNameForTest(suite, test) {
+    return suite.name + &quot;/&quot; + test.name;
+}
+
</ins><span class="cx"> function populateSettings() {
</span><span class="cx">     var suitesDiv = document.getElementById(&quot;suites&quot;);
</span><ins>+
+    var suitesList = document.createElement(&quot;ul&quot;);
+    suitesDiv.appendChild(suitesList);
+
</ins><span class="cx">     Suites.forEach(function(suite) {
</span><del>-        var suiteDiv = document.createDocumentFragment();
</del><ins>+        var suiteItem = document.createElement(&quot;li&quot;);
+        suitesList.appendChild(suiteItem);
</ins><span class="cx"> 
</span><del>-        var label = document.createElement(&quot;label&quot;);
-        var checkbox = document.createElement(&quot;input&quot;);
-        checkbox.setAttribute(&quot;type&quot;, &quot;checkbox&quot;);
-        checkbox.suite = suite;
-        if (+localStorage.getItem(suite.name)) {
-            checkbox.checked = true;
-        }
-        label.appendChild(checkbox);
-        label.appendChild(document.createTextNode(&quot; &quot; + suite.name));
</del><ins>+        var suiteLabel = document.createElement(&quot;label&quot;);
+        suiteItem.appendChild(suiteLabel);
</ins><span class="cx"> 
</span><del>-        suiteDiv.appendChild(label);
-        suiteDiv.appendChild(document.createElement(&quot;br&quot;));
-        suitesDiv.appendChild(suiteDiv);
</del><ins>+        var suiteCheckbox = document.createElement(&quot;input&quot;);
+        suiteCheckbox.setAttribute(&quot;type&quot;, &quot;checkbox&quot;);
+        suiteCheckbox.suite = suite;
+        suiteCheckbox.onchange = updateSuiteSelection;
+        suiteLabel.appendChild(suiteCheckbox);
+        suiteLabel.appendChild(document.createTextNode(&quot; &quot; + suite.name));
+
+        var testsList = document.createElement(&quot;ul&quot;);
+        suiteItem.appendChild(testsList);
+
+        suite.tests.forEach(function(test) {
+            var testItem = document.createElement(&quot;li&quot;);
+            testsList.appendChild(testItem);
+
+            var testLabel = document.createElement(&quot;label&quot;);
+            testItem.appendChild(testLabel);
+
+            var testCheckbox = document.createElement(&quot;input&quot;);
+            testCheckbox.setAttribute(&quot;type&quot;, &quot;checkbox&quot;);
+            testCheckbox.test = test;
+            testCheckbox.onchange = updateTestSelection;
+            if (+localStorage.getItem(localStorageNameForTest(suite, test)))
+                testCheckbox.checked = true;
+            testLabel.appendChild(testCheckbox);
+            testLabel.appendChild(document.createTextNode(&quot; &quot; + test.name));
+        });
+
+        updateSuiteCheckbox(testsList, suiteCheckbox);
</ins><span class="cx">     });
</span><span class="cx"> 
</span><span class="cx">     var interval = localStorage.getItem(&quot;test-interval&quot;);
</span><span class="lines">@@ -179,4 +260,4 @@
</span><span class="cx">         document.getElementById(&quot;test-interval&quot;).value = interval;
</span><span class="cx">     }
</span><span class="cx"> }
</span><del>-document.addEventListener(&quot;DOMContentLoaded&quot;, populateSettings);
</del><span class="cx">\ No newline at end of file
</span><ins>+document.addEventListener(&quot;DOMContentLoaded&quot;, initialize);
</ins></span></pre></div>
<a id="trunkPerformanceTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/ChangeLog (191700 => 191701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/ChangeLog        2015-10-28 22:59:03 UTC (rev 191700)
+++ trunk/PerformanceTests/ChangeLog        2015-10-28 23:11:37 UTC (rev 191701)
</span><span class="lines">@@ -1,3 +1,38 @@
</span><ins>+2015-10-27  Jon Lee  &lt;jonlee@apple.com&gt;
+
+        Add an option to make the graphics benchmark runs a specific test
+        https://bugs.webkit.org/show_bug.cgi?id=150528
+        rdar://problem/23246614
+
+        Reviewed by Zalan Bujtas.
+
+        Add a checkbox that lets the user list all of the available tests, and select
+        the ones to run repeatedly. The test checkboxes will update the state of the suite
+        checkbox. The selected tests are stored in localStorage to make it easy to do
+        repeated runs.
+
+        * Animometer/runner/animometer.html: Add a checkbox to show individual tests.
+        Update other markup.
+        * Animometer/runner/resources/animometer.css: Make the settings area a little wider
+        to accommodate the longer names of the tests
+        * Animometer/runner/resources/animometer.js:
+        (startBenchmark): Change the way that the suites are fed into the benchmark
+        runner. Go through each of the suites and their tests, and create a new Suite
+        with just the enabled tests. While enumerating store the enabled tests into
+        localStorage.
+        (initialize): Initialization routine (taking over populateSettings). When the
+        checkbox for showing tests is toggled, add or remove a class on #suites to show
+        the individual tests.
+        (updateSuiteSelection): Called whenever the user toggles the checkbox for a suite.
+        Either select all or none of the tests.
+        (updateTestSelection): Called whenever the user toggles the checkbox for a test.
+        (updateSuiteCheckbox): Update the state of the test's suite's checkbox to
+        indeterminate if there is at least one enabled test, unchecked if none are selected,
+        and checked if all are selected.
+        (localStorageNameForTest): Helper function to get the name of the test to use as
+        a key to localStorage.
+        (populateSettings): Add the tests for each suite into an inner list.
+
</ins><span class="cx"> 2015-10-26  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add an option to output the results of the graphics benchmark in JSON format
</span></span></pre>
</div>
</div>

</body>
</html>