794d839215c305a698dd87cee3919d56c1629756
[platform/core/uifw/dali-core.git] / dali / integration-api / trace.h
1 #ifndef DALI_INTEGRATION_TRACE_H
2 #define DALI_INTEGRATION_TRACE_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <string>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26
27 namespace Dali
28 {
29 namespace Integration
30 {
31 namespace Trace
32 {
33 /**
34  * Used by tracing macros to log a context message
35  * @param[in] start a bool to indicate start (true) or end (false) of the tracing / logging
36  * @param[in] tag a unique event tag name
37  * @param[in] message an additional message for this trace. Ignore if it is nullptr
38  */
39 DALI_CORE_API void LogContext(bool start, const char* tag, const char* message = nullptr);
40
41 /**
42  * typedef for the LogContextFunction function.
43  */
44 using LogContextFunction = void (*)(bool, const char*, const char*);
45
46 /**
47  * A LogContextFunction function has to be installed for every thread that wants to use tracing.
48  * This should be done by the adaptor.
49  * The LogContextFunction function can be different for each thread.
50  * @param LogContextFunction the Log Context function to install
51  */
52 DALI_CORE_API void InstallLogContextFunction(const LogContextFunction& logContextFunction);
53
54 /********************************************************************************
55  *                                    Filter                                    *
56  ********************************************************************************/
57
58 #ifdef TRACE_ENABLED
59
60 /**
61  * The Filter object is used by the DALI_TRACE_BEGIN macro and others to determine if the tracing
62  * should take place, and routes the tracing via the platform abstraction's LogMessage.
63  *
64  * It provides the ability to turn tracing on or off.
65  *
66  */
67 class DALI_CORE_API Filter
68 {
69 public:
70   /**
71    * Test if trace is enabled for this filter.
72    * @return true if trace is enabled;
73    */
74   inline bool IsTraceEnabled()
75   {
76     return mTraceEnabled;
77   }
78
79   /**
80    * Enable tracing on this filter.
81    */
82   inline void EnableTrace()
83   {
84     mTraceEnabled = true;
85   }
86
87   /**
88    * Disable tracing on this filter.
89    */
90   inline void DisableTrace()
91   {
92     mTraceEnabled = false;
93   }
94
95   /**
96    * Create a new filter whose trace can be modified through the use of an environment variable.
97    *
98    * @param[in] trace The default trace level. If true, function tracing is on.
99    * @param[in] environmentVariableName The environment variable name used in order to change the trace.
100    *
101    * @info To modify trace at runtime, you should define your filter as shown below:
102    *
103    * @code
104    * Trace::Filter* filter = Trace::Filter::New( false, "TRACE_ENV" );
105    * @endcode
106    *
107    * And to use it when running an executable:
108    * @code
109    * TRACE_ENV=1 dali-demo  // Trace ON
110    * TRACE_ENV=0 dali-demo  // Trace OFF
111    * @endcode
112    */
113   static Filter* New(bool trace, const char* environmentVariableName);
114
115   /**
116    * Begin trace.
117    * @param[in] tagName - a unique event tag name.
118    */
119   void BeginTrace(const char* tagName);
120
121   /**
122    * Begin trace.
123    * @param[in] tagName - a unique event tag name.
124    * @param[in] message - an additional message for this trace if needs.
125    */
126   void BeginTrace(const char* tagName, const char* message);
127
128   /**
129    * End trace.
130    * @param[in] tagName - a unique event tag name.
131    */
132   void EndTrace(const char* tagName);
133
134   /**
135    * End trace.
136    * @param[in] tagName - a unique event tag name.
137    * @param[in] message - an additional message for this trace if needs.
138    */
139   void EndTrace(const char* tagName, const char* message);
140
141   /**
142    * Enable trace on all filters.
143    */
144   static void EnableGlobalTrace();
145
146   /**
147    * Disable trace on all filters.
148    */
149   static void DisableGlobalTrace();
150
151 private:
152   /**
153    * Constructor.
154    * @param[in] trace - whether this filter allows tracing.
155    */
156   Filter(bool trace)
157   : mTraceEnabled(trace)
158   {
159   }
160
161 private:
162   bool mTraceEnabled;
163 };
164
165 /********************************************************************************
166  *                                  Trace Macros                                *
167  ********************************************************************************/
168
169 /*
170  * These macros allow the instrumentation of methods.
171  */
172
173 /**
174  * The Tracer object is used by the DALI_TRACE_SCOPE and DALI_TRACE_FUNCTION macros
175  * and uses filter object which in tun routes the tracing via the platform abstraction's LogMessage.
176  *
177  */
178 class DALI_CORE_API Tracer final
179 {
180 public:
181   Tracer(Filter* filter, const char* tag);
182   ~Tracer();
183
184 public:
185   const char* mTag;
186   Filter*     mFilter;
187 };
188
189 /**
190  * For initialization of trace filter, please use DALI_INIT_TRACE_FILTER macro i.e. DALI_INIT_TRACE_FILTER( gFilter, "TRACE_COMBINED", true );
191  * To start tracing, please use DALI_TRACE_BEGIN macro i.e. DALI_TRACE_BEGIN( gFilter, "RENDERING" );
192  * To end tracing, please use DALI_TRACE_END macro i.e. DALI_TRACE_END( gFilter, "RENDERING" );
193  * For scoped tracing, please use DALI_TRACE_SCOPE macro i.e. DALI_TRACE_SCOPE( gFilter, "RENDERING" );
194  * For function tracing, please use DALI_TRACE_FUNCTION macro i.e. DALI_TRACE_FUNCTION( gFilter );
195  */
196
197 /**
198  * Initialization of trace filter
199  * @ref Filter::New
200  */
201 #define DALI_INIT_TRACE_FILTER(name, environmentVariableName, enable)                                               \
202   namespace                                                                                                         \
203   {                                                                                                                 \
204   Dali::Integration::Trace::Filter* name = Dali::Integration::Trace::Filter::New(enable, #environmentVariableName); \
205   }
206
207 /**
208  * Start of tracing
209  */
210 #define DALI_TRACE_BEGIN(filter, tag)    \
211   if(filter && filter->IsTraceEnabled()) \
212   {                                      \
213     filter->BeginTrace(tag);             \
214   }
215
216 #define DALI_TRACE_BEGIN_WITH_MESSAGE(filter, tag, message) \
217   if(filter && filter->IsTraceEnabled())                    \
218   {                                                         \
219     filter->BeginTrace(tag, message);                       \
220   }
221
222 /**
223  * End of tracing
224  */
225 #define DALI_TRACE_END(filter, tag)      \
226   if(filter && filter->IsTraceEnabled()) \
227   {                                      \
228     filter->EndTrace(tag);               \
229   }
230
231 #define DALI_TRACE_END_WITH_MESSAGE(filter, tag, message) \
232   if(filter && filter->IsTraceEnabled())                  \
233   {                                                       \
234     filter->EndTrace(tag, message);                       \
235   }
236
237 /**
238  * Used for function tracing. It logs tracing of the fuction from start to end.
239  */
240 #define DALI_TRACE_FUNCTION(filter) \
241   Dali::Integration::Trace::Tracer logTraceFunction(filter, ASSERT_LOCATION);
242
243 /**
244  * Used for scope tracing. It logs tracing around a scope.
245  */
246 #define DALI_TRACE_SCOPE(filter, tag) \
247   Dali::Integration::Trace::Tracer logTracerScope(filter, tag);
248
249 #else // TRACE_ENABLED
250
251 #define DALI_INIT_TRACE_FILTER(name, tag, enable)
252 #define DALI_TRACE_BEGIN(filter, tag)
253 #define DALI_TRACE_BEGIN_WITH_MESSAGE(filter, tag, message)
254 #define DALI_TRACE_END(filter, tag)
255 #define DALI_TRACE_END_WITH_MESSAGE(filter, tag, message)
256 #define DALI_TRACE_FUNCTION(filter)
257 #define DALI_TRACE_SCOPE(filter, tag)
258
259 #endif
260
261 } // namespace Trace
262
263 } // namespace Integration
264
265 } // namespace Dali
266
267 #endif // DALI_INTEGRATION_TRACE_H