1 /*
2  * This file is part of EasyRPG Player.
3  *
4  * EasyRPG Player is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * EasyRPG Player is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef EP_INSTRUMENTATION_H
19 #define EP_INSTRUMENTATION_H
20 
21 #if defined(PLAYER_INSTRUMENTATION) && PLAYER_INSTRUMENTATION == VTune
22 #define PLAYER_INSTRUMENTATION_VTUNE
23 #endif
24 
25 #ifdef PLAYER_INSTRUMENTATION_VTUNE
26 #include <ittnotify.h>
27 #endif
28 #include <cassert>
29 
30 class Instrumentation {
31 public:
32 	/**
33 	 * Must be called once on startup to initialize the instrumentation framework.
34 	 *
35 	 * @param name name of instrumentation domain
36 	 */
37 	static void Init(const char* name);
38 
39 	/** Call at the beginning of a frame */
40 	static void FrameBegin();
41 
42 	/** Call at the end of a frame */
43 	static void FrameEnd();
44 
45 	/** RAII wrapper around FrameBegin() / FrameEnd() */
46 	class FrameScope {
47 	public:
48 		/**
49 		 * Create a FrameScope
50 		 *
51 		 * @param frame_begin if true, call Begin()
52 		 */
53 		FrameScope(bool frame_begin = true);
54 
55 		FrameScope(const FrameScope&) = delete;
56 		FrameScope& operator=(const FrameScope&) = delete;
57 
58 		/** Take ownership of Frame scope */
59 		FrameScope(FrameScope&&) noexcept;
60 		/** Take ownership of Frame scope */
61 		FrameScope& operator=(FrameScope&&) noexcept;
62 
63 		/** Calls End() */
64 		~FrameScope();
65 
66 		/** Calls FrameBegin() if not already begin */
67 		void Begin() noexcept;
68 		/** Calls FrameEnd() if Begin() was called */
69 		void End() noexcept;
70 		/** Disables the FrameScope */
71 		void Dismiss() noexcept;
72 	private:
73 		bool begun = false;
74 	};
75 
76 private:
77 #ifdef PLAYER_INSTRUMENTATION_VTUNE
78 	static __itt_domain* domain;
79 #endif
80 };
81 
FrameBegin()82 inline void Instrumentation::FrameBegin() {
83 #ifdef PLAYER_INSTRUMENTATION_VTUNE
84 	assert(domain);
85 	__itt_frame_begin_v3(domain, nullptr);
86 #endif
87 }
FrameEnd()88 inline void Instrumentation::FrameEnd() {
89 #ifdef PLAYER_INSTRUMENTATION_VTUNE
90 	assert(domain);
91 	__itt_frame_end_v3(domain, nullptr);
92 #endif
93 }
94 
FrameScope(bool frame_begin)95 inline Instrumentation::FrameScope::FrameScope(bool frame_begin)
96 {
97 	if (frame_begin) {
98 		Begin();
99 	}
100 }
101 
FrameScope(FrameScope && o)102 inline Instrumentation::FrameScope::FrameScope(FrameScope&& o) noexcept
103 	: begun(o.begun)
104 {
105 	o.begun = false;
106 }
107 
108 inline Instrumentation::FrameScope& Instrumentation::FrameScope::operator=(FrameScope&& o) noexcept
109 {
110 	if (this != &o) {
111 		End();
112 		begun = o.begun;
113 		o.begun = false;
114 	}
115 	return *this;
116 }
117 
~FrameScope()118 inline Instrumentation::FrameScope::~FrameScope() {
119 	End();
120 }
121 
Begin()122 inline void Instrumentation::FrameScope::Begin() noexcept {
123 	if (!begun) {
124 		Instrumentation::FrameBegin();
125 		begun = true;
126 	}
127 }
128 
End()129 inline void Instrumentation::FrameScope::End() noexcept {
130 	if (begun) {
131 		Instrumentation::FrameEnd();
132 		begun = false;
133 	}
134 }
135 
Dismiss()136 inline void Instrumentation::FrameScope::Dismiss() noexcept {
137 	begun = false;
138 }
139 
140 #endif
141