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 // call this on frame start
89 // call this on frame end
96 // don't fuckup pairing of there, 'cause they can be nested!
106 // iterator
108 function xprofItCount (): Integer; // from current item to eol (not including children, but including current item)
109 // current item info
119 function xprofItNext (): Boolean; // move to next sibling; false: no more siblings (and current item is unchanged)
122 implementation
124 const
130 // ////////////////////////////////////////////////////////////////////////// //
132 {$IF DEFINED(LINUX)}
133 var
135 {$ENDIF}
136 begin
138 begin
139 {$IF DEFINED(LINUX)}
143 {$ELSE}
145 {$ENDIF}
151 begin
158 begin
165 begin
168 {$IF DEFINED(LINUX)}
170 {$ELSE}
172 {$ENDIF}
177 begin
180 {$IF DEFINED(LINUX)}
182 {$ELSE}
184 {$ENDIF}
189 begin
192 {$IF DEFINED(LINUX)}
194 {$ELSE}
196 {$ENDIF}
201 begin
202 //FillChar(self, sizeof(self), 0);
205 //mStartPosition: TBaseMesure;
210 begin
211 //if mRunning then exit;
215 {$IF DEFINED(LINUX)}
217 {$ELSE}
219 {$ENDIF}
224 var
226 {$IF DEFINED(LINUX)}
228 {$ENDIF}
229 begin
230 {$IF DEFINED(LINUX)}
233 begin
236 end
237 else
238 begin
243 {$ELSE}
246 {$ENDIF}
251 begin
258 // ////////////////////////////////////////////////////////////////////////// //
259 // high-level profiler
260 {$IF DEFINED(STOPWATCH_IS_HERE)}
261 type
272 var
281 // call this on frame start
283 begin
293 // call this on frame end
295 begin
298 begin
306 // don't fuckup pairing of there, 'cause they can be nested!
307 //FIXME: rewrite without schlemiel's algo!
309 var
312 begin
326 // link to list
328 begin
329 // child
332 begin
334 end
335 else
336 begin
340 end
341 else
342 begin
343 // top level
345 begin
357 var
359 begin
365 // go back to parent
371 begin
372 //SetLength(xpsecs, 1024); // 'cause why not? 'cause don't pay for something you may not need
377 // ////////////////////////////////////////////////////////////////////////// //
378 // iterator
382 // all items
384 begin
389 function xprofNameAt (idx: Integer): AnsiString; begin if xptimer.isRunning or (idx < 0) or (idx >= xpsused) then result := '' else result := xpsecs[idx].name; end;
390 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;
391 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;
392 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;
393 function xprofLevelAt (idx: Integer): Integer; begin if xptimer.isRunning or (idx < 0) or (idx >= xpsused) then result := 0 else result := xpsecs[idx].level; end;
396 // false: no sections
398 begin
409 // from current item to eol (not including children, but including current item)
411 var
413 begin
417 begin
424 // current item info
425 function xprofItName (): AnsiString; begin if (xitcur = -1) then result := '' else result := xpsecs[xitcur].name; end;
426 function xprofItMicro (): Int64; begin if (xitcur = -1) then result := 0 else result := xpsecs[xitcur].timer.elapsedMicro; end;
427 function xprofItMilli (): Int64; begin if (xitcur = -1) then result := 0 else result := xpsecs[xitcur].timer.elapsedMilli; end;
428 function xprofItHasChildren (): Boolean; begin if (xitcur = -1) then result := false else result := (xpsecs[xitcur].firstChild <> -1); end;
429 function xprofItIsChild (): Boolean; begin if (xitcur = -1) then result := false else result := (xpsecs[xitcur].parent <> -1); end;
430 function xprofItLevel (): Integer; begin if (xitcur = -1) then result := 0 else result := xpsecs[xitcur].level; end;
432 // dive into childrens
434 begin
436 begin
438 end
439 else
440 begin
446 // pop into parent
448 begin
450 begin
452 end
453 else
454 begin
460 // move to next sibling; false: no more siblings (and current item is unchanged)
462 begin
464 begin
466 end
467 else
468 begin
474 {$ELSE}
492 // current item info
504 {$ENDIF}
506 begin
507 {$IF DEFINED(STOPWATCH_IS_HERE)}
509 {$ENDIF}