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