1 #ifndef __DALI_INTEGRATION_DEBUG_H__
2 #define __DALI_INTEGRATION_DEBUG_H__
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #include <dali/public-api/common/vector-wrapper.h>
27 #include <dali/public-api/object/property-map.h>
30 #include <dali/public-api/common/dali-common.h>
32 // Using Debug namespace alias shortens the log usage significantly
33 namespace Dali{namespace Integration{namespace Log{}}}
34 namespace Debug = Dali::Integration::Log;
46 #if defined(DEBUG_ENABLED)
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;
54 struct DebugPropertyValueMap
56 DebugStringValueContainer stringValues;
57 DebugIndexValueContainer intValues;
60 // Fake globals for gdb typedefs
61 extern Dali::DebugPropertyValueArray gValueArray;
62 extern Dali::DebugPropertyValueMap gValueMap;
79 * Used by logging macros to log a message along with function/class name
80 * @param level debug level
81 * @param format string format
83 DALI_IMPORT_API void LogMessage(enum DebugPriority level,const char *format, ...);
86 * typedef for the logging function.
88 typedef void (*LogFunction)(DebugPriority priority, std::string& message);
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
97 DALI_IMPORT_API void InstallLogFunction(const LogFunction& logFunction);
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.
103 DALI_IMPORT_API void UninstallLogFunction();
105 /********************************************************************************
106 * Error/Warning macros. *
107 ********************************************************************************/
110 * Provides unfiltered logging for global error level messages
112 #define DALI_LOG_ERROR(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, "%s " format, __PRETTY_FUNCTION__, ## args)
114 #define DALI_LOG_ERROR_NOFN(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, format, ## args)
116 #define DALI_LOG_WARNING_NOFN(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, format, ## args)
119 * Provides unfiltered logging for fps monitor
121 #define DALI_LOG_FPS(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
124 * Provides unfiltered logging for update status
126 #define DALI_LOG_UPDATE_STATUS(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
129 * Provides unfiltered logging for render information
131 #define DALI_LOG_RENDER_INFO(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
134 * Provides unfiltered logging for release
136 #define DALI_LOG_RELEASE_INFO(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
141 * Provides unfiltered logging for global warning level messages
143 #define DALI_LOG_WARNING(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, "%s " format, __PRETTY_FUNCTION__, ## args)
146 #else // DEBUG_ENABLED
148 // Don't warn on release build
149 #define DALI_LOG_WARNING(format, args...)
153 /********************************************************************************
155 ********************************************************************************/
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.
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.
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.
181 class DALI_IMPORT_API Filter
184 typedef std::list<Filter*> FilterList;
185 typedef std::list<Filter*>::iterator FilterIter;
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.
194 bool IsEnabledFor(LogLevel level) { return level != Debug::NoLogging && level <= mLoggingLevel;}
197 * Test if trace is enabled for this filter.
198 * @return true if trace is enabled;
200 bool IsTraceEnabled() { return mTraceEnabled; }
203 * Enable tracing on this filter.
205 void EnableTrace() { mTraceEnabled = true; }
208 * Disable tracing on this filter.
210 void DisableTrace() { mTraceEnabled = false; }
213 * Set the log level for this filter. Setting to a higher value than Debug::General also
216 void SetLogLevel(LogLevel level) { mLoggingLevel = level; }
219 * Perform the logging for this filter.
221 void Log(LogLevel level, const char* format, ...);
224 * Create a new filter whose debug level and trace can be modified through the use of an
225 * environment variable.
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.
232 * @info To modify logg level/trace at runtime, you can should define your filter as shown below:
235 * Debug::Filter* filter = Debug::Filter::New( Debug::NoLogging, false, "FILTER_ENV" );
238 * And to use it when running an executable:
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
246 static Filter* New(LogLevel level, bool trace, const char * environmentVariableName );
249 * Enable trace on all filters.
251 void EnableGlobalTrace();
254 * Disable trace on all filters.
256 void DisableGlobalTrace();
262 * @param[in] level - the highest log level.
263 * @param[in] trace - whether this filter allows tracing.
265 Filter(LogLevel level, bool trace) : mLoggingLevel(level), mTraceEnabled(trace), mNesting(0) {}
267 static FilterList* GetActiveFilters();
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.
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;
286 LogLevel mLoggingLevel;
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()
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)
306 /********************************************************************************
307 * General Logging macros *
308 ********************************************************************************/
312 #define DALI_LOG_INFO(filter, level, format, args...) \
313 if(filter && filter->IsEnabledFor(level)) { filter->Log(level, format, ## args); }
315 #else // DEBUG_ENABLED
317 #define DALI_LOG_INFO(filter, level, format, args...)
319 #endif // DEBUG_ENABLED
322 /********************************************************************************
324 ********************************************************************************/
327 * These macros allow the instrumentation of methods. These translate into calls
328 * to LogMessage(DebugInfo).
333 class DALI_IMPORT_API TraceObj
336 TraceObj(Filter* filter, const char* fmt, ...);
340 std::string mMessage;
345 #define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...) \
346 Dali::Integration::Log::TraceObj debugTraceObj(filter, "%s: " format, __PRETTY_FUNCTION__, ## args)
348 #define DALI_LOG_TRACE_METHOD(filter) \
349 Dali::Integration::Log::TraceObj debugTraceObj(filter, __PRETTY_FUNCTION__)
352 #else // DEBUG_ENABLED
354 #define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...)
355 #define DALI_LOG_TRACE_METHOD(filter)
360 /********************************************************************************
361 * Extra object debug *
362 ********************************************************************************/
367 * Warning, this macro changes the current scope, so should usually be put at the
368 * end of the class definition.
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.
373 #define DALI_LOG_OBJECT_STRING_DECLARATION \
375 std::string mDebugString;
378 * Print all the actor tree names
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(); \
387 DALI_LOG_ERROR_NOFN("Actor tree: %s\n", branch.str().c_str()); \
391 * Allows one object to set another object's debug string
393 #define DALI_LOG_SET_OBJECT_STRING(object, string) (object->mDebugString = string)
396 * Allows one object to set another object's std::string easily
398 #define DALI_LOG_FMT_OBJECT_STRING(object, fmt, args...) (object->mDebugString = FormatToString(fmt, ## args))
401 * Allows one object to get another object's debug string
403 #define DALI_LOG_GET_OBJECT_STRING(object) (object->mDebugString)
406 * Get the C string (for use in formatted logging)
408 #define DALI_LOG_GET_OBJECT_C_STR(object) (object->mDebugString.c_str())
411 * Filtered logging of the object's debug string
413 #define DALI_LOG_OBJECT(filter, object) DALI_LOG_INFO(filter, Debug::General, object->mDebugString)
416 #else // DEBUG_ENABLED
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)
428 /********************************************************************************
430 ********************************************************************************/
433 * Helper method to translate a color to a string.
434 * @param[in] color - the color to translate
435 * @return string - the text representation of the color.
437 DALI_IMPORT_API std::string ColorToString(const Vector4& color);
440 * Helper method to translate a vector4 to a string.
441 * @param[in] v - the vector
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.
446 DALI_IMPORT_API std::string Vector4ToString(const Vector4& v, size_t precision=3, size_t indent=0);
449 * Helper method to translate a vector4 to a string.
450 * @param[in] v - the vector
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.
455 DALI_IMPORT_API std::string Vector3ToString(const Vector3& v, size_t precision=3, size_t indent=0);
458 * Helper method to translate a quaternion to a string.
459 * @param[in] q the quaternion
460 * @param[in] precision - the precision to write the float data.
461 * @param[in] indent - the indent level to use.
462 * @return string - the text representation of the quaternion.
464 DALI_IMPORT_API std::string QuaternionToString(const Quaternion& q, size_t precision=3, size_t indent=0);
467 * Helper method to translate a 3x3 matrix to a string.
468 * @param[in] m - the matrix
469 * @param[in] precision - the precision to write the float data.
470 * @param[in] indent - the indent level to use.
471 * @return string - the text representation of the vector.
473 DALI_IMPORT_API std::string Matrix3ToString(const Matrix3& m, size_t precision=3, size_t indent=0);
476 * Helper method to translate a 4x4 matrix to a string.
477 * @param[in] m - the matrix
478 * @param[in] precision - the precision to write the float data.
479 * @param[in] indent - the indent level to use.
480 * @return string - the text representation of the vector.
482 DALI_IMPORT_API std::string MatrixToString(const Matrix& m, size_t precision=3, size_t indent=0);
488 * Filtered write of a matrix
490 #define DALI_LOG_MATRIX(filter, matrix) DALI_LOG_INFO(filter, Debug::General, MatrixToString(matrix))
493 * Filtered write of a vector
495 #define DALI_LOG_VECTOR4(filter, vector) DALI_LOG_INFO(filter, Debug::General, Vector4ToString(vector))
498 * Filtered write of a vector
500 #define DALI_LOG_VECTOR3(filter, vector) DALI_LOG_INFO(filter, Debug::General, Vector3ToString(vector))
503 * Filtered write of a color
505 #define DALI_LOG_COLOR(filter, color) DALI_LOG_INFO(filter, Debug::General, ColorToString(color))
509 #define DALI_LOG_MATRIX(filter, matrix)
510 #define DALI_LOG_VECTOR4(filter,vector)
511 #define DALI_LOG_VECTOR3(filter,vector)
512 #define DALI_LOG_COLOR(filter, color)
516 /********************************************************************************
517 * Time instrumentation *
518 ********************************************************************************/
520 #if defined(DEBUG_ENABLED)
522 void GetNanoseconds( uint64_t& timeInNanoseconds );
524 #define DALI_LOG_TIMER_START( timeVariable ) \
525 uint64_t timeVariable##1; \
526 Debug::GetNanoseconds( timeVariable##1 );
528 #define DALI_LOG_TIMER_END( timeVariable, filter, level, preString) \
529 uint64_t timeVariable##2; \
530 Debug::GetNanoseconds( timeVariable##2 ); \
531 DALI_LOG_INFO( filter, level, preString " %ld uSec\n", ((timeVariable##2-timeVariable##1)/1000));
533 #else // DEBUG_ENABLED
535 #define DALI_LOG_TIMER_START( timeVariable )
536 #define DALI_LOG_TIMER_END( timeVariable, filter, level, preString)
545 #endif // __DALI_INTEGRATION_DEBUG_H__