Emscripten workarounds and llvm syntax fixes
[platform/core/uifw/dali-core.git] / dali / integration-api / debug.h
1 #ifndef __DALI_INTEGRATION_DEBUG_H__
2 #define __DALI_INTEGRATION_DEBUG_H__
3
4 //
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 //
7 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // EXTERNAL INCLUDES
21 #include <string>
22 #include <list>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26
27 // Using Debug namespace alias shortens the log usage significantly
28 namespace Dali{namespace Integration{namespace Log{}}}
29 namespace Debug = Dali::Integration::Log;
30
31 namespace Dali
32 {
33
34 struct Vector2;
35 struct Vector3;
36 struct Vector4;
37 class Matrix3;
38 class Matrix;
39 class Quaternion;
40
41 namespace Integration
42 {
43 namespace Log
44 {
45
46 // environment variable for enabling/disabling logging in different threads
47 #define DALI_ENV_ENABLE_LOG "DALI_ENABLE_LOG"
48 // values of the environment variable
49 #define DALI_LOG_OFF               "FALSE"            ///< disable log messages from all threads. Do not log resource creation / destruction
50 #define DALI_LOG_EVENT_THREAD      "EVENT"            ///< enable log messages from event thread. Do not log resource creation / destruction
51 #define DALI_LOG_UPDATE_THREAD     "UPDATE"           ///< enable log messages from update thread. Do not log resource creation / destruction
52 #define DALI_LOG_RENDER_THREAD     "RENDER"           ///< enable log messages from render thread. Do not log resource creation / destruction
53 #define DALI_LOG_RESOURCE_THREADS  "RESOURCE_LOADER"  ///< enable log messages from render thread. Do not log resource creation / destruction
54 #define DALI_LOG_ALL_THREADS       "ALL"              ///< enable log messages from all threads. Do not log resource creation / destruction
55 #define DALI_LOG_RESOURCE_LIFETIME "RESOURCE_LOG"     ///< log resource creation / destruction. Enables logging on all threads.
56
57 // environment variable for enabling/disabling fps tracking
58 #define DALI_ENV_FPS_TRACKING "DALI_FPS_TRACKING"
59
60 // environment variable for enabling/disabling fps tracking
61 #define DALI_ENV_UPDATE_STATUS_INTERVAL "DALI_UPDATE_STATUS_INTERVAL"
62
63 enum DebugPriority
64 {
65   DebugInfo,
66   DebugWarning,
67   DebugError,
68   DebugResources
69 };
70
71 /**
72  * Control logging in separate threads.
73  * If DEBUG_ENABLED macro is not defined, only errors and resource lifetime messages are logged.
74  */
75 enum LoggingOptions
76 {
77   LogNone              = 0,
78   LogEventThread       = 1 << 0,
79   LogUpdateThread      = 1 << 1,
80   LogRenderThread      = 1 << 2,
81   LogResourceThreads   = 1 << 3,
82   LogResourceLifetime  = 1 << 4
83 };
84
85 /**
86  * Return log settings (bitfield) based on the value set in environment
87  * @param[in] setting the string contained in DALI_ENABLE_LOG env. variable (or NULL if not set)
88  * @return a bitfield with all the relevant LoggingOptions values set
89  */
90 DALI_IMPORT_API unsigned int ParseLogOptions (const char* setting);
91
92 /**
93  * Used by logging macros to log a message along with function/class name
94  * @param level debug level
95  * @param format string format
96  */
97 DALI_IMPORT_API void LogMessage(enum DebugPriority level,const char *format, ...);
98
99 /**
100  * typedef for the logging function.
101  */
102 typedef void (*LogFunction)(DebugPriority priority, std::string& message);
103
104 /**
105  * A log function has to be installed for every thread that wants to use logging.
106  * This should be done by the adaptor.
107  * The log function can be different for each thread.
108  * @param logFunction the log function to install
109  * @param logOpts the log options to save in thread
110  */
111 DALI_IMPORT_API void InstallLogFunction(const LogFunction& logFunction, unsigned int logOpts);
112
113 /**
114  * A log function has to be uninstalled for every thread that wants to use logging.
115  * The log function can be different for each thread.
116  */
117 DALI_IMPORT_API void UninstallLogFunction();
118
119 /********************************************************************************
120  *                            Error/Warning  macros.                            *
121  ********************************************************************************/
122
123 /**
124  * Provides unfiltered logging for global error level messages
125  */
126 #define DALI_LOG_ERROR(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError,   "%s " format, __PRETTY_FUNCTION__, ## args)
127
128 #define DALI_LOG_ERROR_NOFN(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, format, ## args)
129
130 /**
131  * Provides unfiltered logging for resource usage
132  */
133 #define DALI_LOG_RESOURCE(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugResources, format, ## args)
134
135 /**
136  * Provides unfiltered logging for fps monitor
137  */
138 #define DALI_LOG_FPS(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
139
140 /**
141  * Provides unfiltered logging for update status
142  */
143 #define DALI_LOG_UPDATE_STATUS(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
144
145 /**
146  * Provides unfiltered logging for render information
147  */
148 #define DALI_LOG_RENDER_INFO(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
149
150 #ifdef DEBUG_ENABLED
151
152 /**
153  * Provides unfiltered logging for global warning level messages
154  */
155 #define DALI_LOG_WARNING(format, args...)   Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, "%s " format, __PRETTY_FUNCTION__, ## args)
156
157
158 #else // DEBUG_ENABLED
159
160 // Don't warn on release build
161 #define DALI_LOG_WARNING(format, args...)
162
163 #endif
164
165 /********************************************************************************
166  *                                    Filter                                    *
167  ********************************************************************************/
168
169 #ifdef DEBUG_ENABLED
170
171 /**
172  * Enumeration of logging levels.
173  * Used by the filters to provide multiple log levels.
174  * In general, the higher the value, the more debug is available for that filter.
175  */
176 enum LogLevel
177 {
178   NoLogging   = 0,
179   Concise     = 1,
180   General     = 2,
181   Verbose     = 3
182 };
183
184
185 /**
186  * The Filter object is used by the DALI_LOG_INFO macro and others to determine if the logging
187  * should take place, and routes the logging via the platform abstraction's LogMessage.
188  *
189  * It provides a logging level. If this is set to zero, then DALI_LOG_INFO won't log anything.
190  * It provides the ability to turn tracing on or off.
191  *
192  */
193 class DALI_IMPORT_API Filter
194 {
195 public:
196   typedef std::list<Filter*>           FilterList;
197   typedef std::list<Filter*>::iterator FilterIter;
198
199 public:
200
201   /**
202    * Test if the filter is enabled for the given logging level
203    * @param[in] level - the level to test.
204    * @return true if this level of logging is enabled.
205    */
206   bool IsEnabledFor(LogLevel level) { return level != Debug::NoLogging && level <= mLoggingLevel;}
207
208   /**
209    * Test if trace is enabled for this filter.
210    * @return true if trace is enabled;
211    */
212   bool IsTraceEnabled() { return mTraceEnabled; }
213
214   /**
215    * Enable tracing on this filter.
216    */
217   void EnableTrace() { mTraceEnabled = true; }
218
219   /**
220    * Disable tracing on this filter.
221    */
222   void DisableTrace() { mTraceEnabled = false; }
223
224   /**
225    * Set the log level for this filter. Setting to a higher value than Debug::General also
226    * enables General;
227    */
228   void SetLogLevel(LogLevel level) { mLoggingLevel = level; }
229
230   /**
231    * Perform the logging for this filter.
232    */
233   void Log(LogLevel level, const char* format, ...);
234
235   /**
236    * Create a new filter whose debug level and trace can be modified through the use of an
237    * environment variable.
238    *
239    * @param[in] level The default log level
240    * @param[in] trace The default trace level. If true, function tracing is on.
241    * @param[in] environmentVariableName The environment variable name used in order to change the
242    *                                    log level or trace.
243    *
244    * @info To modify logg level/trace at runtime, you can should define your filter as shown below:
245    *
246    * @code
247    * Debug::Filter* filter = Debug::Filter::New( Debug::NoLogging, false, "FILTER_ENV" );
248    * @endcode
249    *
250    * And to use it when running an executable:
251    * @code
252    * FILTER_ENV=3 dali-demo        // LogLevel Verbose,   Trace using default
253    * FILTER_ENV=1,true dali-demo   // LogLevel Concise,   Trace ON
254    * FILTER_ENV=2,false dali-demo  // LogLevel General,   Trace OFF
255    * FILTER_ENV=0,true dali-demo   // LogLevel NoLogging, Trace ON
256    * @endcode
257    */
258   static Filter* New(LogLevel level, bool trace, const char * environmentVariableName );
259
260   /**
261    * Enable trace on all filters.
262    */
263   void EnableGlobalTrace();
264
265   /**
266    * Disable trace on all filters.
267    */
268   void DisableGlobalTrace();
269
270 private:
271
272   /**
273    * Constructor.
274    * @param[in] level - the highest log level.
275    * @param[in] trace - whether this filter allows tracing.
276    */
277   Filter(LogLevel level, bool trace) : mLoggingLevel(level), mTraceEnabled(trace), mNesting(0) {}
278
279   static FilterList* GetActiveFilters();
280
281 public:
282   // High level filters. If these filters are too broad for your current requirement, then
283   // you can add a filter to your own class or source file. If you do, use Filter::New()
284   // to tell this class about it.
285
286   static Filter *gRender;
287   static Filter *gResource;
288   static Filter *gGLResource;
289   static Filter *gObject;
290   static Filter *gImage;
291   static Filter *gModel;
292   static Filter *gNode;
293   static Filter *gElement;
294   static Filter *gActor;
295   static Filter *gShader;
296   static Filter *gDynamics;
297
298 private:
299   LogLevel mLoggingLevel;
300   bool     mTraceEnabled;
301 public:
302   int      mNesting;
303
304 };
305
306
307 #define  DALI_LOG_FILTER_SET_LEVEL(filter, level) filter->SetLogLevel(level)
308 #define  DALI_LOG_FILTER_ENABLE_TRACE(filter)     filter->EnableTrace()
309 #define  DALI_LOG_FILTER_DISABLE_TRACE(filter)    filter->DisableTrace()
310
311 #else
312
313 #define  DALI_LOG_FILTER_SET_LEVEL(filter, level)
314 #define  DALI_LOG_FILTER_ENABLE_TRACE(filter)
315 #define  DALI_LOG_FILTER_DISABLE_TRACE(filter)
316
317 #endif
318
319 /********************************************************************************
320  *                            General Logging macros                            *
321  ********************************************************************************/
322
323 #ifdef DEBUG_ENABLED
324
325 #define DALI_LOG_INFO(filter, level, format, args...)                        \
326   if(filter && filter->IsEnabledFor(level)) { filter->Log(level, format,  ## args); }
327
328 #else // DEBUG_ENABLED
329
330 #define DALI_LOG_INFO(filter, level, format, args...)
331
332 #endif // DEBUG_ENABLED
333
334
335 /********************************************************************************
336  *                                  Trace Macros                                *
337  ********************************************************************************/
338
339 /*
340  * These macros allow the instrumentation of methods. These translate into calls
341  * to LogMessage(DebugInfo).
342  */
343
344 #ifdef DEBUG_ENABLED
345
346 class DALI_IMPORT_API TraceObj
347 {
348 public:
349   TraceObj(Filter* filter, const char* fmt, ...);
350   ~TraceObj();
351
352 public:
353   std::string mMessage;
354   Filter* mFilter;
355 };
356
357
358 #define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...)                 \
359   Dali::Integration::Log::TraceObj debugTraceObj(filter, "%s: " format, __PRETTY_FUNCTION__, ## args)
360
361 #define DALI_LOG_TRACE_METHOD(filter)                                      \
362   Dali::Integration::Log::TraceObj debugTraceObj(filter, __PRETTY_FUNCTION__)
363
364
365 #else // DEBUG_ENABLED
366
367 #define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...)
368 #define DALI_LOG_TRACE_METHOD(filter)
369
370
371 #endif
372
373 /********************************************************************************
374  *                              Extra object debug                              *
375  ********************************************************************************/
376
377 #ifdef DEBUG_ENABLED
378
379 /**
380  * Warning, this macro changes the current scope, so should usually be put at the
381  * end of the class definition.
382  *
383  * Suggest that the value is usually set to the object's name.
384  * Warning - this will increase the size of the object for a debug build.
385  */
386 #define DALI_LOG_OBJECT_STRING_DECLARATION \
387 public: \
388   std::string mDebugString;
389
390 /**
391  * Allows one object to set another object's debug string
392  */
393 #define DALI_LOG_SET_OBJECT_STRING(object, string) (object->mDebugString = string)
394
395 /**
396  * Allows one object to set another object's std::string easily
397  */
398 #define DALI_LOG_FMT_OBJECT_STRING(object, fmt, args...) (object->mDebugString = FormatToString(fmt, ## args))
399
400 /**
401  * Allows one object to get another object's debug string
402  */
403 #define DALI_LOG_GET_OBJECT_STRING(object) (object->mDebugString)
404
405 /**
406  * Get the C string (for use in formatted logging)
407  */
408 #define DALI_LOG_GET_OBJECT_C_STR(object) (object->mDebugString.c_str())
409
410 /**
411  * Filtered logging of the object's debug string
412  */
413 #define DALI_LOG_OBJECT(filter, object)  DALI_LOG_INFO(filter, Debug::General, object->mDebugString)
414
415
416 #else // DEBUG_ENABLED
417
418 #define DALI_LOG_OBJECT_STRING_DECLARATION
419 #define DALI_LOG_SET_OBJECT_STRING(object, string)
420 #define DALI_LOG_FMT_OBJECT_STRING(object, fmt, args...)
421 #define DALI_LOG_GET_OBJECT_STRING(object)
422 #define DALI_LOG_GET_OBJECT_C_STR(object) ""
423 #define DALI_LOG_OBJECT(filter, object)
424
425 #endif
426
427 /********************************************************************************
428  *                                Helper writers                                *
429  ********************************************************************************/
430
431 /**
432  * Helper method to translate a color to a string.
433  * @param[in] color - the color to translate
434  * @return string - the text representation of the color.
435  */
436 DALI_IMPORT_API std::string ColorToString(const Vector4& color);
437
438 /**
439  * Helper method to translate a vector4 to a string.
440  * @param[in] v - the vector
441  * @param[in] precision - the precision to write the float data.
442  * @param[in] indent - the indent level to use.
443  * @return string - the text representation of the vector.
444  */
445 DALI_IMPORT_API std::string Vector4ToString(const Vector4& v, size_t precision=3, size_t indent=0);
446
447 /**
448  * Helper method to translate a vector4 to a string.
449  * @param[in] v - the vector
450  * @param[in] precision - the precision to write the float data.
451  * @param[in] indent - the indent level to use.
452  * @return string - the text representation of the vector.
453  */
454 DALI_IMPORT_API std::string Vector3ToString(const Vector3& v, size_t precision=3, size_t indent=0);
455
456 /**
457  * Helper method to translate a quaternion to a string.
458  * @param[in] q the quaternion
459  * @param[in] precision - the precision to write the float data.
460  * @param[in] indent - the indent level to use.
461  * @return string - the text representation of the quaternion.
462  */
463 DALI_IMPORT_API std::string QuaternionToString(const Quaternion& q, size_t precision=3, size_t indent=0);
464
465 /**
466  * Helper method to translate a 3x3 matrix to a string.
467  * @param[in] m - the matrix
468  * @param[in] precision - the precision to write the float data.
469  * @param[in] indent - the indent level to use.
470  * @return string - the text representation of the vector.
471  */
472 DALI_IMPORT_API std::string Matrix3ToString(const Matrix3& m, size_t precision=3, size_t indent=0);
473
474 /**
475  * Helper method to translate a 4x4 matrix to a string.
476  * @param[in] m - the matrix
477  * @param[in] precision - the precision to write the float data.
478  * @param[in] indent - the indent level to use.
479  * @return string - the text representation of the vector.
480  */
481 DALI_IMPORT_API std::string MatrixToString(const Matrix& m, size_t precision=3, size_t indent=0);
482
483 #ifdef DEBUG_ENABLED
484
485
486 /**
487  * Filtered write of a matrix
488  */
489 #define DALI_LOG_MATRIX(filter, matrix)  DALI_LOG_INFO(filter, Debug::General, MatrixToString(matrix))
490
491 /**
492  * Filtered write of a vector
493  */
494 #define DALI_LOG_VECTOR4(filter, vector) DALI_LOG_INFO(filter, Debug::General, Vector4ToString(vector))
495
496 /**
497  * Filtered write of a vector
498  */
499 #define DALI_LOG_VECTOR3(filter, vector) DALI_LOG_INFO(filter, Debug::General, Vector3ToString(vector))
500
501 /**
502  * Filtered write of a color
503  */
504 #define DALI_LOG_COLOR(filter, color)    DALI_LOG_INFO(filter, Debug::General, ColorToString(color))
505
506 #else
507
508 #define DALI_LOG_MATRIX(filter, matrix)
509 #define DALI_LOG_VECTOR4(filter,vector)
510 #define DALI_LOG_VECTOR3(filter,vector)
511 #define DALI_LOG_COLOR(filter, color)
512
513 #endif
514
515 }}} // Dali/Integration/Debug namespaces
516
517
518 #endif // __DALI_INTEGRATION_DEBUG_H__