Adds performance logging

pull/1916/head
Martin Boonk 2022-02-28 20:14:19 +01:00
parent cdab89b414
commit 9fdad181e0
1 changed files with 87 additions and 22 deletions

View File

@ -1,7 +1,46 @@
var face = require("Storage").readJSON("imageclock.face.json"); var face = require("Storage").readJSON("imageclock.face.json");
var resources = require("Storage").readJSON("imageclock.resources.json"); var resources = require("Storage").readJSON("imageclock.resources.json");
var performanceLog = {};
var startPerfLog = ()=>{};
var endPerfLog = ()=>{};
var printPerfLog = ()=>print("Deactivated");
if (true){
startPerfLog = function(name){
var time = getTime();
if (!performanceLog.start) performanceLog.start={};
performanceLog.start[name] = time;
};
endPerfLog = function (name){
var time = getTime();
if (!performanceLog.last) performanceLog.last={};
var duration = time - performanceLog.start[name];
performanceLog.last[name] = duration;
if (!performanceLog.cum) performanceLog.cum={};
if (!performanceLog.cum[name]) performanceLog.cum[name] = 0;
performanceLog.cum[name] += duration;
if (!performanceLog.count) performanceLog.count={};
if (!performanceLog.count[name]) performanceLog.count[name] = 0;
performanceLog.count[name]++;
};
printPerfLog = function(){
var result = "";
var keys = [];
for (var c in performanceLog.cum){
keys.push(c);
}
keys.sort();
for (var k of keys){
print(k, "last:", (performanceLog.last[k] * 1000).toFixed(0), "average:", (performanceLog.cum[k]/performanceLog.count[k]*1000).toFixed(0), "total:", (performanceLog.cum[k] * 1000).toFixed(0));
}
};
}
function prepareImg(resource){ function prepareImg(resource){
startPerfLog("prepareImg");
//print("prepareImg: ", resource); //print("prepareImg: ", resource);
var result = cacheBuffers ? resource : { var result = cacheBuffers ? resource : {
@ -19,7 +58,7 @@ function prepareImg(resource){
//print("buffer from file"); //print("buffer from file");
result.buffer = E.toArrayBuffer(atob(require("Storage").read(resource.file))); result.buffer = E.toArrayBuffer(atob(require("Storage").read(resource.file)));
result.file = undefined; result.file = undefined;
} else if (resource.compressed && (resource.dataOffset == undefined)){ } else if (resource.compressed && (resource.dataOffset === undefined)){
//print("buffer from compressed"); //print("buffer from compressed");
result.buffer = require("heatshrink").decompress(atob(resource.compressed)); result.buffer = require("heatshrink").decompress(atob(resource.compressed));
result.compressed = undefined; result.compressed = undefined;
@ -44,10 +83,12 @@ function prepareImg(resource){
result.paletteData = undefined; result.paletteData = undefined;
} }
endPerfLog("prepareImg");
return result; return result;
} }
function getByPath(object, path, lastElem){ function getByPath(object, path, lastElem){
startPerfLog("getByPath");
//print("getByPath", path,lastElem); //print("getByPath", path,lastElem);
var current = object; var current = object;
if (path.length) { if (path.length) {
@ -61,6 +102,7 @@ function getByPath(object, path, lastElem){
//print("Found by lastElem", lastElem); //print("Found by lastElem", lastElem);
current = current["" + lastElem]; current = current["" + lastElem];
} }
endPerfLog("getByPath");
if (typeof current == "function"){ if (typeof current == "function"){
//print("current was function"); //print("current was function");
return undefined; return undefined;
@ -73,6 +115,7 @@ function splitNumberToDigits(num){
} }
function drawNumber(element, offset){ function drawNumber(element, offset){
startPerfLog("drawNumber");
var number = numbers[element.Value](); var number = numbers[element.Value]();
var spacing = element.Spacing ? element.Spacing : 0; var spacing = element.Spacing ? element.Spacing : 0;
var unit = element.Unit; var unit = element.Unit;
@ -85,13 +128,13 @@ function drawNumber(element, offset){
//print("drawNumber: ", number, element, offset); //print("drawNumber: ", number, element, offset);
if (number) number = number.toFixed(0); if (number) number = number.toFixed(0);
if (!element.Refresh || element.Refresh == "Always" || (element.Refresh == "Change" && element.lastDrawnValue && element.lastDrawnValue != number)){ if (checkRedraw(element,number)){
//var numberOffset = updateOffset(element, offset); //var numberOffset = updateOffset(element, offset);
var numberOffset = offset; var numberOffset = offset;
var isNegative; var isNegative;
var digits; var digits;
if (number == undefined){ if (typeof number !== "number"){
isNegative = true; isNegative = true;
digits = []; digits = [];
numberOfDigits = 0; numberOfDigits = 0;
@ -185,6 +228,8 @@ function drawNumber(element, offset){
drawElement({X:currentX,Y:firstDigitY}, numberOffset, element.ImagePath, getMultistate(element.Unit,"unknown")); drawElement({X:currentX,Y:firstDigitY}, numberOffset, element.ImagePath, getMultistate(element.Unit,"unknown"));
} }
element.lastDrawnValue = number; element.lastDrawnValue = number;
endPerfLog("drawNumber");
} }
} }
@ -194,6 +239,7 @@ function setColors(properties){
} }
function drawElement(pos, offset, path, lastElem){ function drawElement(pos, offset, path, lastElem){
startPerfLog("drawElement");
//print("drawElement ",pos, offset, path, lastElem); //print("drawElement ",pos, offset, path, lastElem);
//print("drawElement offset", offset, pos.X, pos.Y); //print("drawElement offset", offset, pos.X, pos.Y);
var resource = getByPath(resources, path, lastElem); var resource = getByPath(resources, path, lastElem);
@ -215,13 +261,16 @@ function drawElement(pos, offset, path, lastElem){
} }
//print("options", options); //print("options", options);
//print("Memory before drawing", process.memory(false)); //print("Memory before drawing", process.memory(false));
startPerfLog("drawElement_g.drawImage");
g.drawImage(image ,(imageOffset.X ? imageOffset.X : 0) + (pos.X ? pos.X : 0),(imageOffset.Y ? imageOffset.Y :0) + (pos.Y ? pos.Y : 0), options); g.drawImage(image ,(imageOffset.X ? imageOffset.X : 0) + (pos.X ? pos.X : 0),(imageOffset.Y ? imageOffset.Y :0) + (pos.Y ? pos.Y : 0), options);
endPerfLog("drawElement_g.drawImage");
} else { } else {
//print("Could not create image from", resource); //print("Could not create image from", resource);
} }
} else { } else {
//print("Could not get resource from", path, lastElem); //print("Could not get resource from", path, lastElem);
} }
endPerfLog("drawElement");
} }
function checkRedraw(element, newValue){ function checkRedraw(element, newValue){
@ -255,15 +304,12 @@ function getMultistate(name, defaultValue){
} }
function drawScale(scale, offset){ function drawScale(scale, offset){
startPerfLog("drawScale");
//print("drawScale", scale, offset); //print("drawScale", scale, offset);
var segments = scale.Segments; var segments = scale.Segments;
var value = numbers[scale.Value]();
var maxValue = getValue(scale.MaxValue, 1);
var minValue = getValue(scale.MinValue, 0);
var imageIndex = scale.ImageIndex !== undefined ? scale.ImageIndex : 0; var imageIndex = scale.ImageIndex !== undefined ? scale.ImageIndex : 0;
value = value/maxValue; var value = scaledown(scale.Value, scale.MinValue, scale.MaxValue);
value -= minValue;
//print("Value is ", value, "(", maxValue, ",", minValue, ")"); //print("Value is ", value, "(", maxValue, ",", minValue, ")");
@ -277,6 +323,7 @@ function drawScale(scale, offset){
} }
scale.lastDrawnValue = segmentsToDraw; scale.lastDrawnValue = segmentsToDraw;
} }
endPerfLog("drawScale");
} }
function drawDigit(element, offset, digit){ function drawDigit(element, offset, digit){
@ -284,11 +331,12 @@ function drawDigit(element, offset, digit){
} }
function drawImage(image, offset, name){ function drawImage(image, offset, name){
startPerfLog("drawImage");
var imageOffset = updateColors(image, offset); var imageOffset = updateColors(image, offset);
if (image.ImagePath) { if (image.ImagePath) {
//print("drawImage", image, offset, name); //print("drawImage", image, offset, name);
if (image.Value && image.Steps){ if (image.Value && image.Steps){
var steps = Math.floor(scaledown(getValue(image.Value), getValue(image.MinValue, 0), getValue(image.MaxValue, 1)) * (image.Steps - 1)); var steps = Math.floor(scaledown(image.Value, image.MinValue, image.MaxValue) * (image.Steps - 1));
//print("Step", steps, "of", image.Steps); //print("Step", steps, "of", image.Steps);
drawElement(image, imageOffset, image.ImagePath, "" + steps); drawElement(image, imageOffset, image.ImagePath, "" + steps);
} else if (image.ImageIndex !== undefined) { } else if (image.ImageIndex !== undefined) {
@ -301,9 +349,11 @@ function drawImage(image, offset, name){
setColors(imageOffset); setColors(imageOffset);
g.drawImage(prepareImg(file),image.X + imageOffset.X, image.Y + imageOffset.Y); g.drawImage(prepareImg(file),image.X + imageOffset.X, image.Y + imageOffset.Y);
} }
endPerfLog("drawImage");
} }
function drawCodedImage(image, offset){ function drawCodedImage(image, offset){
startPerfLog("drawCodedImage");
var code = getValue(image.Value); var code = getValue(image.Value);
//print("drawCodedImage", image, offset, code); //print("drawCodedImage", image, offset, code);
@ -329,6 +379,7 @@ function drawCodedImage(image, offset){
} }
image.lastDrawnValue = code; image.lastDrawnValue = code;
} }
startPerfLog("drawCodedImage");
} }
function getWeatherCode(){ function getWeatherCode(){
@ -361,11 +412,13 @@ function getWeatherTemperature(){
} }
function updateOffset(element, offset){ function updateOffset(element, offset){
startPerfLog("updateOffset");
var newOffset = { X: offset.X ? offset.X : 0, Y: offset.Y ? offset.Y : 0 }; var newOffset = { X: offset.X ? offset.X : 0, Y: offset.Y ? offset.Y : 0 };
if (element && element.X) newOffset.X += element.X; if (element && element.X) newOffset.X += element.X;
if (element && element.Y) newOffset.Y += element.Y; if (element && element.Y) newOffset.Y += element.Y;
newOffset = updateColors(element, newOffset); newOffset = updateColors(element, newOffset);
//print("Updated offset from ", offset, "to", newOffset); //print("Updated offset from ", offset, "to", newOffset);
endPerfLog("updateOffset");
return newOffset; return newOffset;
} }
@ -388,6 +441,7 @@ function scaledown(value, min, max){
} }
function rotate(center, coords, rotation) { function rotate(center, coords, rotation) {
startPerfLog("rotate");
var value = scaledown(rotation.RotationValue, rotation.MinRotationValue, rotation.MaxRotationValue); var value = scaledown(rotation.RotationValue, rotation.MinRotationValue, rotation.MaxRotationValue);
value -= rotation.RotationOffset ? rotation.RotationOffset : 0; value -= rotation.RotationOffset ? rotation.RotationOffset : 0;
value *= 360; value *= 360;
@ -400,15 +454,19 @@ function rotate(center, coords, rotation) {
sin = Math.sin(radians), sin = Math.sin(radians),
x = (cos * (coords.X - center.X)) + (sin * (coords.Y - center.Y)) + center.X, x = (cos * (coords.X - center.X)) + (sin * (coords.Y - center.Y)) + center.X,
y = (cos * (coords.Y - center.Y)) - (sin * (coords.X - center.X)) + center.Y; y = (cos * (coords.Y - center.Y)) - (sin * (coords.X - center.X)) + center.Y;
endPerfLog("rotate");
return {X:x,Y:y}; return {X:x,Y:y};
} }
function drawPoly(element, offset){ function drawPoly(element, offset){
startPerfLog("drawPoly");
var vertices = []; var vertices = [];
var primitiveOffset = offset.clone(); var primitiveOffset = offset.clone();
if (element.X) primitiveOffset.X += element.X; if (element.X) primitiveOffset.X += element.X;
if (element.Y) primitiveOffset.Y += element.Y; if (element.Y) primitiveOffset.Y += element.Y;
startPerfLog("drawPoly_transform");
for (var c of element.Vertices){ for (var c of element.Vertices){
if (element.RotationValue){ if (element.RotationValue){
var rotated = rotate({X:0,Y:0}, c, element); var rotated = rotate({X:0,Y:0}, c, element);
@ -419,15 +477,22 @@ function drawPoly(element, offset){
vertices.push(c.Y + primitiveOffset.Y); vertices.push(c.Y + primitiveOffset.Y);
} }
} }
endPerfLog("drawPoly_transform");
if (element.ForegroundColor) g.setColor(element.ForegroundColor); if (element.ForegroundColor) g.setColor(element.ForegroundColor);
if (element.Filled){ if (element.Filled){
startPerfLog("drawPoly_g.fillPoly");
g.fillPoly(vertices,true); g.fillPoly(vertices,true);
endPerfLog("drawPoly_g.fillPoly");
} }
if (element.BackgroundColor) g.setColor(element.BackgroundColor); if (element.BackgroundColor) g.setColor(element.BackgroundColor);
startPerfLog("drawPoly_g.drawPoly");
g.drawPoly(vertices,true); g.drawPoly(vertices,true);
endPerfLog("drawPoly_g.drawPoly");
startPerfLog("drawPoly");
} }
var numbers = {}; var numbers = {};
@ -482,6 +547,7 @@ multistates.WeatherTemperatureUnit = () => { return getWeatherTemperature().unit
multistates.StepsGoal = () => { return (numbers.Steps() >= stepsgoal) ? "on": "off"; }; multistates.StepsGoal = () => { return (numbers.Steps() >= stepsgoal) ? "on": "off"; };
function drawMultiState(element, offset){ function drawMultiState(element, offset){
startPerfLog("drawMultiState");
//print("drawMultiState", element, offset); //print("drawMultiState", element, offset);
var value = multistates[element.Value](); var value = multistates[element.Value]();
if (checkRedraw(element, value)){ if (checkRedraw(element, value)){
@ -489,9 +555,11 @@ function drawMultiState(element, offset){
drawImage(element, offset, value); drawImage(element, offset, value);
element.lastDrawnValue = value; element.lastDrawnValue = value;
} }
endPerfLog("drawMultiState");
} }
function draw(element, offset){ function draw(element, offset){
startPerfLog("draw_"+ path.join("_"));
var initial = !element; var initial = !element;
if (initial){ if (initial){
element = face; element = face;
@ -500,7 +568,6 @@ function draw(element, offset){
if (!offset.Y) offset.Y = 0; if (!offset.Y) offset.Y = 0;
g.clear(); g.clear();
} }
var elementOffset = updateOffset(element, offset); var elementOffset = updateOffset(element, offset);
setColors(elementOffset); setColors(elementOffset);
@ -508,10 +575,8 @@ function draw(element, offset){
for (var current in element){ for (var current in element){
//print("Handling ", current, " with offset ", elementOffset); //print("Handling ", current, " with offset ", elementOffset);
//print("Handling ", current); startPerfLog("draw_handling_"+ path.join("_")+"_"+current);
var currentElement = element[current]; var currentElement = element[current];
//var start = Date.now();
try { try {
switch(current){ switch(current){
case "X": case "X":
@ -549,12 +614,15 @@ function draw(element, offset){
draw(currentElement, elementOffset); draw(currentElement, elementOffset);
//print("Done next level"); //print("Done next level");
} }
endPerfLog("draw_handling_"+ path.join("_")+"_"+current);
//print("Drawing of", current, "in", (Date.now() - start).toFixed(0), "ms"); //print("Drawing of", current, "in", (Date.now() - start).toFixed(0), "ms");
} catch (e){ } catch (e){
print("Error during drawing of", current, "in", element, e, e.stack); print("Error during drawing of", current, "in", element, e, e.stack);
} }
} }
//print("Finished drawing loop in", Date.now() - start); //print("Finished drawing loop");
endPerfLog("draw_"+ path.join("_"));
} }
var pulse,alt,temp,press; var pulse,alt,temp,press;
@ -574,8 +642,9 @@ function initialDraw(){
isDrawing = true; isDrawing = true;
requestedDraws = 0; requestedDraws = 0;
//print(new Date().toISOString(), "Drawing start"); //print(new Date().toISOString(), "Drawing start");
var start = Date.now(); startPerfLog("initialDraw");
draw(undefined, zeroOffset); draw(undefined, zeroOffset);
endPerfLog("initialDraw");
//print(new Date().toISOString(), "Drawing done", (Date.now() - start).toFixed(0)); //print(new Date().toISOString(), "Drawing done", (Date.now() - start).toFixed(0));
isDrawing = false; isDrawing = false;
if (requestedDraws > 0){ if (requestedDraws > 0){
@ -588,30 +657,28 @@ function initialDraw(){
function handleHrm(e){ function handleHrm(e){
if (e.confidence > 70){ if (e.confidence > 70){
var change = pulse != e.bpm
pulse = e.bpm; pulse = e.bpm;
if (!redrawEvents || redrawEvents.includes("HRM") && !Bangle.isLocked()){ if (!redrawEvents || redrawEvents.includes("HRM") && !Bangle.isLocked()){
//print("Redrawing on HRM"); //print("Redrawing on HRM");
changeFromEvent |= change; initialDraw();
} }
} }
} }
function handlePressure(e){ function handlePressure(e){
var change = (alt != e.altitude) || (temp != e.temperature) || (press != e.pressure);
alt = e.altitude; alt = e.altitude;
temp = e.temperature; temp = e.temperature;
press = e.pressure; press = e.pressure;
if (!redrawEvents || redrawEvents.includes("pressure") && !Bangle.isLocked()){ if (!redrawEvents || redrawEvents.includes("pressure") && !Bangle.isLocked()){
//print("Redrawing on pressure"); //print("Redrawing on pressure");
changeFromEvent |= change; initialDraw();
} }
} }
function handleCharging(e){ function handleCharging(e){
if (!redrawEvents || redrawEvents.includes("charging") && !Bangle.isLocked()){ if (!redrawEvents || redrawEvents.includes("charging") && !Bangle.isLocked()){
//print("Redrawing on charging"); //print("Redrawing on charging");
changeFromEvent = true; initialDraw();
} }
} }
@ -636,8 +703,6 @@ function setMatchedInterval(callable, time, intervalHandler){
var unlockedDrawInterval; var unlockedDrawInterval;
var lockedDrawInterval; var lockedDrawInterval;
var changeFromEvent = false;
var lockedRedraw = getByPath(face, ["Properties","Redraw","Locked"]) || 60000; var lockedRedraw = getByPath(face, ["Properties","Redraw","Locked"]) || 60000;
var unlockedRedraw = getByPath(face, ["Properties","Redraw","Unlocked"]) || 1000; var unlockedRedraw = getByPath(face, ["Properties","Redraw","Unlocked"]) || 1000;
var defaultRedraw = getByPath(face, ["Properties","Redraw","Default"]) || "Always"; var defaultRedraw = getByPath(face, ["Properties","Redraw","Default"]) || "Always";