225e9de4e324cfd4f6fada7088713c578eca5ca6
1 (* Copyright (C) DooM 2D:Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 // stopwatch timer to measure short periods (like frame rendering phases)
17 // TStopWatch is based on the code by Inoussa OUEDRAOGO, Copyright (c) 2012
18 {$INCLUDE a_modes.inc}
21 interface
23 uses
24 SysUtils,
25 {$IF DEFINED(LINUX)}
26 {$DEFINE STOPWATCH_IS_HERE}
27 unixtype, linux
28 {$ELSEIF DEFINED(WINDOWS)}
29 {$DEFINE STOPWATCH_IS_HERE}
30 Windows
31 {$ELSE}
32 {$IFDEF STOPWATCH_IS_HERE}
33 {$UNDEF STOPWATCH_IS_HERE}
34 {$ENDIF}
35 {$WARNING You suck!}
36 {$ENDIF}
37 ;
39 {$IF DEFINED(STOPWATCH_IS_HERE)}
40 type
42 private
43 {$IF DEFINED(LINUX)}
45 {$ELSE}
47 {$ENDIF}
49 strict private
53 strict private
58 strict private
67 public
74 public
84 {$ENDIF}
87 const
90 type
92 private
95 private
102 private
108 public
119 public
123 public
135 // call this on frame start
137 // call this on frame end
144 // don't fuckup pairing of there, 'cause they can be nested!
154 // iterator
156 function xprofItCount (): Integer; // from current item to eol (not including children, but including current item)
157 // current item info
167 function xprofItNext (): Boolean; // move to next sibling; false: no more siblings (and current item is unchanged)
170 implementation
172 const
178 // ////////////////////////////////////////////////////////////////////////// //
180 {$IF DEFINED(LINUX)}
181 var
183 {$ENDIF}
184 begin
186 begin
187 {$IF DEFINED(LINUX)}
191 {$ELSE}
193 {$ENDIF}
199 begin
206 begin
213 begin
216 {$IF DEFINED(LINUX)}
218 {$ELSE}
220 {$ENDIF}
225 begin
228 {$IF DEFINED(LINUX)}
230 {$ELSE}
232 {$ENDIF}
237 begin
240 {$IF DEFINED(LINUX)}
242 {$ELSE}
244 {$ENDIF}
249 begin
250 //FillChar(self, sizeof(self), 0);
253 //mStartPosition: TBaseMesure;
258 begin
259 //if mRunning then exit;
263 {$IF DEFINED(LINUX)}
265 {$ELSE}
267 {$ENDIF}
272 var
274 {$IF DEFINED(LINUX)}
276 {$ENDIF}
277 begin
278 {$IF DEFINED(LINUX)}
281 begin
284 end
285 else
286 begin
291 {$ELSE}
294 {$ENDIF}
299 begin
306 // ////////////////////////////////////////////////////////////////////////// //
307 // high-level profiler
308 {$IF DEFINED(STOPWATCH_IS_HERE)}
309 type
320 var
329 // call this on frame start
331 begin
341 // call this on frame end
343 begin
346 begin
354 // don't fuckup pairing of there, 'cause they can be nested!
355 //FIXME: rewrite without schlemiel's algo!
357 var
360 begin
374 // link to list
376 begin
377 // child
380 begin
382 end
383 else
384 begin
388 end
389 else
390 begin
391 // top level
393 begin
405 var
407 begin
413 // go back to parent
419 begin
420 //SetLength(xpsecs, 1024); // 'cause why not? 'cause don't pay for something you may not need
425 // ////////////////////////////////////////////////////////////////////////// //
426 // iterator
430 // all items
432 begin
437 function xprofNameAt (idx: Integer): AnsiString; begin if xptimer.isRunning or (idx < 0) or (idx >= xpsused) then result := '' else result := xpsecs[idx].name; end;
438 function xprofMicroAt (idx: Integer): Int64; begin if xptimer.isRunning or (idx < 0) or (idx >= xpsused) then result := 0 else result := xpsecs[idx].timer.elapsedMicro; end;
439 function xprofMilliAt (idx: Integer): Int64; begin if xptimer.isRunning or (idx < 0) or (idx >= xpsused) then result := 0 else result := xpsecs[idx].timer.elapsedMilli; end;
440 function xprofHasChildrenAt (idx: Integer): Boolean; begin if xptimer.isRunning or (idx < 0) or (idx >= xpsused) then result := false else result := (xpsecs[idx].firstChild <> -1); end;
441 function xprofLevelAt (idx: Integer): Integer; begin if xptimer.isRunning or (idx < 0) or (idx >= xpsused) then result := 0 else result := xpsecs[idx].level; end;
444 // false: no sections
446 begin
457 // from current item to eol (not including children, but including current item)
459 var
461 begin
465 begin
472 // current item info
473 function xprofItName (): AnsiString; begin if (xitcur = -1) then result := '' else result := xpsecs[xitcur].name; end;
474 function xprofItMicro (): Int64; begin if (xitcur = -1) then result := 0 else result := xpsecs[xitcur].timer.elapsedMicro; end;
475 function xprofItMilli (): Int64; begin if (xitcur = -1) then result := 0 else result := xpsecs[xitcur].timer.elapsedMilli; end;
476 function xprofItHasChildren (): Boolean; begin if (xitcur = -1) then result := false else result := (xpsecs[xitcur].firstChild <> -1); end;
477 function xprofItIsChild (): Boolean; begin if (xitcur = -1) then result := false else result := (xpsecs[xitcur].parent <> -1); end;
478 function xprofItLevel (): Integer; begin if (xitcur = -1) then result := 0 else result := xpsecs[xitcur].level; end;
480 // dive into childrens
482 begin
484 begin
486 end
487 else
488 begin
494 // pop into parent
496 begin
498 begin
500 end
501 else
502 begin
508 // move to next sibling; false: no more siblings (and current item is unchanged)
510 begin
512 begin
514 end
515 else
516 begin
522 {$ELSE}
540 // current item info
552 {$ENDIF}
555 // ////////////////////////////////////////////////////////////////////////// //
559 var
561 begin
563 if (hisHead = -1) then begin hisHead := 0; curval := 0; for idx := 0 to TProfHistorySize-1 do history[idx] := val; end;
575 begin
576 if (idx < 0) or (idx >= TProfHistorySize) then result := 0 else result := history[(hisHead-idx-1+TProfHistorySize*2) mod TProfHistorySize];
580 // ////////////////////////////////////////////////////////////////////////// //
582 begin
589 begin
596 begin
601 var
603 begin
606 begin
607 // first time?
609 begin
610 //if (length(bars) <> 0) then raise Exception.Create('FUUUUUUUUUUUUUUU');
613 begin
622 // update bars
629 begin
634 begin
639 begin
640 {$IF DEFINED(STOPWATCH_IS_HERE)}
642 {$ENDIF}