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