Merge 'remotes/trunk'
[0ad.git] / source / tools / profiler2 / utilities.js
blob90b9c00e0e7c05e2f8d7b70a372c4cca3d7df16e
1 // Copyright (C) 2016 Wildfire Games.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
21 // Various functions used by several of the tiles.
23 function hslToRgb(h, s, l, a)
25     var r, g, b;
27     if (s == 0)
28     {
29         r = g = b = l;
30     }
31     else
32     {
33         function hue2rgb(p, q, t)
34         {
35             if (t < 0) t += 1;
36             if (t > 1) t -= 1;
37             if (t < 1/6) return p + (q - p) * 6 * t;
38             if (t < 1/2) return q;
39             if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
40             return p;
41         }
43         var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
44         var p = 2 * l - q;
45         r = hue2rgb(p, q, h + 1/3);
46         g = hue2rgb(p, q, h);
47         b = hue2rgb(p, q, h - 1/3);
48     }
50     return 'rgba(' + Math.floor(r * 255) + ',' + Math.floor(g * 255) + ',' + Math.floor(b * 255) + ',' + a + ')';
53 function new_colour(id)
55     var hs = [0, 1/3, 2/3, 1/4, 2/4, 3/4, 1/5, 3/5, 2/5, 4/5];
56     var ss = [1, 0.5];
57     var ls = [0.8, 0.6, 0.9, 0.7];
58     return hslToRgb(hs[id % hs.length], ss[Math.floor(id / hs.length) % ss.length], ls[Math.floor(id / (hs.length*ss.length)) % ls.length], 1);
61 function graph_colour(id)
63     var hs = [0, 1/3, 2/3, 2/4, 3/4, 1/5, 3/5, 2/5, 4/5];
64     return hslToRgb(hs[id % hs.length], 0.7, 0.5, 1);
67 function concat_events(data)
69     var events = [];
70     data.events.forEach(function(ev) {
71         ev.pop(); // remove the dummy null markers
72         Array.prototype.push.apply(events, ev);
73     });
74     return events;
77 function time_label(t, precision = 2)
79     if (t < 0)
80         return "-" + time_label(-t, precision);
81     if (t > 1e-3)
82         return (t * 1e3).toFixed(precision) + 'ms';
83     else
84         return (t * 1e6).toFixed(precision) + 'us';
87 function slice_intervals(data, range)
89     if (!data.intervals.length)
90         return {"tmin":0,"tmax":0,"intervals":[]};
92     var tmin = 0;
93     var tmax = 0;
94     if (range.seconds && data.frames.length)
95     {
96         tmax = data.frames[data.frames.length-1].t1;
97         tmin = data.frames[data.frames.length-1].t1-range.seconds;
98     }
99     else if (range.frames && data.frames.length)
100     {
101         tmax = data.frames[data.frames.length-1].t1;
102         tmin = data.frames[data.frames.length-1-range.frames].t0;
103     }
104     else
105     {
106         tmax = range.tmax;
107         tmin = range.tmin;
108     }
109     var events = { "tmin" : tmin, "tmax" : tmax, "intervals" : [] };
110     for (let itv in data.intervals)
111     {
112         let interval = data.intervals[itv];
113         if (interval.t1 > tmin && interval.t0 < tmax)
114             events.intervals.push(interval);
115     }
116     return events;
119 function smooth_1D(array, i, distance)
121     let value = 0;
122     let total = 0;
123     for (let j = i - distance; j <= i + distance; j++)
124     {
125         value += array[j]*(1+distance*distance - (j-i)*(j-i) );
126         total += (1+distance*distance - (j-i)*(j-i) );
127     }
128     return value/total;
131 function smooth_1D_array(array, distance)
133     let copied = array.slice(0);
134     for (let i =0; i < array.length; ++i)
135     {
136         let value = 0;
137         let total = 0;
138         for (let j = i - distance; j <= i + distance; j++)
139         {
140             value += array[j]*(1+distance*distance - (j-i)*(j-i) );
141             total += (1+distance*distance - (j-i)*(j-i) );
142         }
143         copied[i] = value/total;
144     }
145     return copied;
148 function set_tooltip_handlers(canvas)
150     function do_tooltip(event)
151     {
152         var tooltips = canvas._tooltips;
153         if (!tooltips)
154             return;
156         var relativeX = event.pageX - this.getBoundingClientRect().left - window.scrollX;
157         var relativeY = event.pageY - this.getBoundingClientRect().top - window.scrollY;
159         var text = undefined;
160         for (var i = 0; i < tooltips.length; ++i)
161         {
162             var t = tooltips[i];
163             if (t.x0-1 <= relativeX && relativeX <= t.x1+1 && t.y0 <= relativeY && relativeY <= t.y1)
164             {
165                 text = t.text();
166                 break;
167             }
168         }
169         if (text)
170         {
171             if (text.length > 512)
172                 $('#tooltip').addClass('long');
173             else
174                 $('#tooltip').removeClass('long');
175             $('#tooltip').css('left', (event.pageX+16)+'px');
176             $('#tooltip').css('top', (event.pageY+8)+'px');
177             $('#tooltip').html(text);
178             $('#tooltip').css('visibility', 'visible');
179         }
180         else
181         {
182             $('#tooltip').css('visibility', 'hidden');
183         }
184     }
186     $(canvas).mousemove(function(event) {
187         do_tooltip.call(this, event);
188     });
189     $(canvas).mouseleave(function(event) {
190         $('#tooltip').css('visibility', 'hidden');
191     });