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