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