This repository has been archived on 2023-02-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-benchmark-bundle/benchmark/website/source/utils.js

340 lines
10 KiB
JavaScript
Raw Normal View History

function hash_string_int(s) {
var hash = 1;
for (var i = 0; i < s.length; ++i) {
var ch = s.charCodeAt(i);
hash = (hash * 163 + ch) % 2147483647;
}
return hash;
}
function hash_string_float(s) {
return hash_string_int(s) / 2147483647;
}
function HSVtoRGB(h, s, v) {
var r, g, b, i, f, p, q, t;
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return {r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)};
}
// Generate unique looking color for a given bar index.
function generateBarColor(index, label) {
var u1 = hash_string_float(label);
var u2 = hash_string_float(label.split("").reverse().join(""));
var h = 0, s = 0.8, v = 0.8;
if (label.startsWith("AMD")) {
h = 0;
} else if (label.startsWith("Intel")) {
h = 0.66;
} else if (label.startsWith("Nvidia")) {
h = 0.33;
}
h += ((u1 + u2) * 0.5 - 0.5) * 0.2;
if (h < 0) h = 1.0 - h;
s += (u1 - 0.5) * 0.5;
v += (u2 - 0.5) * 0.25;
var color = HSVtoRGB(h, s, v);
return "rgb(" + Math.round(color.r).toString() + ", " +
Math.round(color.g).toString() + ", " +
Math.round(color.b).toString() + ")";
}
// Correct device name, ensuring it has clear vendor indication,
// and has no trademarks or other things.
function correctDeviceName(name) {
if (name.startsWith("TITAN") ||
name.startsWith("Quadro") ||
name.startsWith("GeForce")) {
return "Nvidia " + name;
}
if (name.startsWith("Radeon")) {
return "AMD " + name;
}
2017-11-08 11:55:29 +01:00
return name.replace(/( @.*)/, "");
}
2017-11-08 11:48:35 +01:00
function strcmp(a, b) {
return ( ( a == b ) ? 0 : ( ( a > b ) ? 1 : -1 ) );
}
function clone(object) {
return jQuery.extend(true, {}, object);
}
function padValue(value, size) {
var s = String(value);
while (s.length < (size || 2)) {
s = "0" + s;
}
return s;
}
function secondsToHumanReadable(seconds) {
var h = Math.floor((seconds %= 86400) / 3600);
var m = Math.floor((seconds %= 3600) / 60);
var s = Math.floor(seconds % 60);
var msec = Math.floor((seconds % 60) % 1 * 100);
var result = "";
if (h != 0) {
result += h + ":";
}
result += padValue(m, 2) + ":";
result += padValue(s, 2) + ".";
result += padValue(msec, 2);
return result;
}
function setDatasetColor(data, is_bar) {
2017-08-18 17:25:33 +02:00
var index = 0;
for (dataset of data.datasets) {
var color = Chart.helpers.color(generateBarColor(index, dataset.label));
2017-08-18 17:25:33 +02:00
dataset.backgroundColor = color.alpha(0.5).rgbString();
dataset.borderColor = color.alpha(1.0).rgbString();
if (is_bar) {
dataset.borderWidth = 1;
} else {
dataset.fill = false;
}
index++;
}
}
function setCorrectDatasetLabels(data) {
for (dataset of data.datasets) {
dataset.label = correctDeviceName(dataset.label);
}
}
2017-11-08 11:48:35 +01:00
function compareDatasets(dataset_a, dataset_b) {
return strcmp(dataset_a.label, dataset_b.label);
}
function sortDataset(data) {
data.datasets.sort(compareDatasets);
}
function prepareDataset(data, is_bar) {
setCorrectDatasetLabels(data);
sortDataset(data);
setDatasetColor(data, is_bar);
}
function findDatasetMaxValue(data) {
var max_value = 0;
for (dataset of data.datasets) {
for (value of dataset.data) {
if (value === null) {
continue;
}
if (typeof value !== "number") {
value = value.y;
}
max_value = Math.max(max_value, value);
}
}
return max_value;
}
function buildChart(ctx, bare_data) {
var data = clone(bare_data);
2017-11-08 11:48:35 +01:00
prepareDataset(data, true);
var my_chart = new Chart(
ctx,
{
type: 'bar',
data: data,
options: { responsive: true,
legend: {position: 'top'},
title: {display: true,
text: 'Benchmark Results'},
scales: {xAxes: [{display: true,
scaleLabel: {display: true,
labelString: 'Scene'}}],
yAxes: [{display: true,
scaleLabel: {display: true,
labelString: 'Render time (sec)'},
ticks: {min: 0}}]},
tooltips: {// mode: 'index',
callbacks: {
footer: function(tooltipItems, data) {
var human_time = "";
tooltipItems.forEach(
function(tooltipItem) {
var render_time = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
human_time = secondsToHumanReadable(render_time);
}
);
if (human_time != "") {
return "Render Time: " + human_time;
}
return "";
},
},
filter: function(item, data) {
var data = data.datasets[item.datasetIndex].data[item.index];
return !isNaN(data) && data !== null;
},
footerFontStyle: 'normal'},
}
});
// TODO(sergey): How can we avoid storing chart in some obscure global variable?
window.my_chart = my_chart;
}
function updateEnabledScenesCallback(bare_data) {
/* Collect list of enabled scenes. */
var enabled_scenes = [];
var disabled_scenes = [];
var scene_index = 0;
for (scene_name of bare_data.labels) {
var id = "scene_" + scene_name + "_id";
var checkbox = document.getElementById(id);
if (checkbox.checked) {
enabled_scenes.push({"index": scene_index, "name": scene_name});
} else {
disabled_scenes.push({"index": scene_index, "name": scene_name});
}
++scene_index;
}
/* Construct new data by making a copy of original one and removing
* disabeld scenes.
*
* Note: we reverse te list so indices for removal are alweays staying
* the same.
*/
disabled_scenes.reverse();
var updated_data = clone(bare_data);
2017-11-08 11:48:35 +01:00
prepareDataset(updated_data, true);
for (scene of disabled_scenes) {
// Remove label first.
updated_data.labels.splice(scene.index, 1);
updated_data.datasets.forEach(function(dataset, dataset_index) {
dataset.data.splice(scene.index, 1);
});
}
/* Update the actual chart. */
var my_chart = window.my_chart;
my_chart.data = updated_data;
my_chart.update();
}
function buildScenesSelector(ctx, bare_data) {
var div = document.createElement("div");
div.className = "scene_selector_container";
for (scene_name of data.labels) {
var span = document.createElement("span");
var checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.name = "scene_" + scene_name;
checkbox.checked = true;
checkbox.id = "scene_" + scene_name + "_id";
checkbox.onclick = function() { updateEnabledScenesCallback(bare_data); };
span.appendChild(checkbox);
var label = document.createElement('label');
label.htmlFor = "scene_" + scene_name + "_id";
label.appendChild(document.createTextNode(scene_name));
span.appendChild(label);
div.appendChild(span);
}
ctx.appendChild(div);
}
function historyChartGetSceneStats(bare_data, scene_name) {
var datasets = [];
for (dataset of bare_data.datasets) {
if (dataset.scene_name != scene_name) {
continue;
}
datasets.push({"data": dataset.data,
"label": dataset.device_name});
}
return {"datasets": datasets};
}
function buildHistoryChart(ctx, bare_data, scene_name) {
var data = historyChartGetSceneStats(bare_data, scene_name);
2017-11-08 11:48:35 +01:00
prepareDataset(data, false);
new Chart(
ctx,
{
type: 'line',
data: data,
options: { responsive: true,
legend: {position: 'top'},
title: {display: true,
text: scene_name + ' benchmark results'},
scales: {xAxes: [{type: "time",
time: {format: 'DD/MM/YYYY HH:mm',
tooltipFormat: 'll HH:mm'},
scaleLabel: {display: true,
labelString: 'Date'}},],
yAxes: [{display: true,
scaleLabel: {display: true,
labelString: 'Render time (sec)'},
ticks: {min: 0}}]},
elements: { line: { tension: 0.000001 } },
}
});
}
2017-11-08 11:48:35 +01:00
function comapreTableRows(row_a, row_b) {
return strcmp(row_a[0], row_b[0]);
}
function sortTableRows(rows) {
rows.sort(comapreTableRows);
}
function buildSpreadsheet(ctx, data) {
// Generate columns for header.
var columns = [{label: "", name: "", width: 300}];
for (label of data.labels) {
columns.push({label: label, name: label});
}
// Generate actual data.
var rows = [];
for (dataset of data.datasets) {
var row = [correctDeviceName(dataset.label)];
for (value of dataset.data) {
if (value == null) {
row.push("");
} else {
row.push(secondsToHumanReadable(value));
}
}
rows.push(row);
}
2017-11-08 11:48:35 +01:00
sortTableRows(rows);
// Create actual table.
$(ctx).jqGrid({
data: rows,
localReader: {repeatitems: true},
datatype: "local",
styleUI : 'Bootstrap',
colModel: columns,
caption: "Spreadsheet",
2017-11-08 11:58:19 +01:00
height: "100%",
rowNum: 999999,
});
}