1 #ifndef __DALI_INTEGRATION_DEBUG_H__
2 #define __DALI_INTEGRATION_DEBUG_H__
5 * Copyright (c) 2018 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.
28 #pragma GCC diagnostic push
29 #pragma GCC diagnostic ignored "-Wshadow"
30 #pragma GCC diagnostic ignored "-Wconversion"
31 #pragma GCC diagnostic ignored "-Wfloat-conversion"
32 #pragma GCC diagnostic ignored "-Wdouble-promotion"
34 #include <dali/public-api/common/vector-wrapper.h>
35 #include <dali/public-api/object/property-map.h>
38 #include <dali/public-api/common/dali-common.h>
40 #pragma GCC diagnostic pop
42 // Using Debug namespace alias shortens the log usage significantly
43 namespace Dali{namespace Integration{namespace Log{}}}
44 namespace Debug = Dali::Integration::Log;
56 #if defined(DEBUG_ENABLED)
58 // Less opaque types for debugger
59 typedef std::vector<Dali::Property::Value> DebugPropertyValueArray;
60 typedef std::pair< Property::Index, Property::Value > DebugIndexValuePair;
61 typedef std::vector<Dali::StringValuePair> DebugStringValueContainer;
62 typedef std::vector< DebugIndexValuePair > DebugIndexValueContainer;
64 struct DebugPropertyValueMap
66 DebugStringValueContainer stringValues;
67 DebugIndexValueContainer intValues;
70 // Fake globals for gdb typedefs
71 extern Dali::DebugPropertyValueArray gValueArray;
72 extern Dali::DebugPropertyValueMap gValueMap;
89 * Used by logging macros to log a message along with function/class name
90 * @param level debug level
91 * @param format string format
93 DALI_CORE_API void LogMessage(enum DebugPriority level,const char *format, ...);
96 * typedef for the logging function.
98 typedef void (*LogFunction)(DebugPriority priority, std::string& message);
101 * A log function has to be installed for every thread that wants to use logging.
102 * This should be done by the adaptor.
103 * The log function can be different for each thread.
104 * @param logFunction the log function to install
105 * @param logOpts the log options to save in thread
107 DALI_CORE_API void InstallLogFunction(const LogFunction& logFunction);
110 * A log function has to be uninstalled for every thread that wants to use logging.
111 * The log function can be different for each thread.
113 DALI_CORE_API void UninstallLogFunction();
115 /********************************************************************************
116 * Error/Warning macros. *
117 ********************************************************************************/
120 * Provides unfiltered logging for global error level messages
122 #define DALI_LOG_ERROR(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, "%s " format, __PRETTY_FUNCTION__, ## args)
124 #define DALI_LOG_ERROR_NOFN(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, format, ## args)
126 #define DALI_LOG_WARNING_NOFN(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, format, ## args)
129 * Provides unfiltered logging for fps monitor
131 #define DALI_LOG_FPS(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
134 * Provides unfiltered logging for update status
136 #define DALI_LOG_UPDATE_STATUS(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
139 * Provides unfiltered logging for render information
141 #define DALI_LOG_RENDER_INFO(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
144 * Provides unfiltered logging for release
146 #define DALI_LOG_RELEASE_INFO(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
151 * Provides unfiltered logging for global warning level messages
153 #define DALI_LOG_WARNING(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, "%s " format, __PRETTY_FUNCTION__, ## args)
156 #else // DEBUG_ENABLED
158 // Don't warn on release build
159 #define DALI_LOG_WARNING(format, args...)
163 /********************************************************************************
165 ********************************************************************************/
170 * Enumeration of logging levels.
171 * Used by the filters to provide multiple log levels.
172 * In general, the higher the value, the more debug is available for that filter.
184 * The Filter object is used by the DALI_LOG_INFO macro and others to determine if the logging
185 * should take place, and routes the logging via the platform abstraction's LogMessage.
187 * It provides a logging level. If this is set to zero, then DALI_LOG_INFO won't log anything.
188 * It provides the ability to turn tracing on or off.
191 class DALI_CORE_API Filter
194 typedef std::list<Filter*> FilterList;
195 typedef std::list<Filter*>::iterator FilterIter;
200 * Test if the filter is enabled for the given logging level
201 * @param[in] level - the level to test.
202 * @return true if this level of logging is enabled.
204 bool IsEnabledFor(LogLevel level) { return level != Debug::NoLogging && level <= mLoggingLevel;}
207 * Test if trace is enabled for this filter.
208 * @return true if trace is enabled;
210 bool IsTraceEnabled() { return mTraceEnabled; }
213 * Enable tracing on this filter.
215 void EnableTrace() { mTraceEnabled = true; }
218 * Disable tracing on this filter.
220 void DisableTrace() { mTraceEnabled = false; }
223 * Set the log level for this filter. Setting to a higher value than Debug::General also
226 void SetLogLevel(LogLevel level) { mLoggingLevel = level; }
229 * Perform the logging for this filter.
231 void Log(LogLevel level, const char* format, ...);
234 * Create a new filter whose debug level and trace can be modified through the use of an
235 * environment variable.
237 * @param[in] level The default log level
238 * @param[in] trace The default trace level. If true, function tracing is on.
239 * @param[in] environmentVariableName The environment variable name used in order to change the
240 * log level or trace.
242 * @info To modify logg level/trace at runtime, you can should define your filter as shown below:
245 * Debug::Filter* filter = Debug::Filter::New( Debug::NoLogging, false, "FILTER_ENV" );
248 * And to use it when running an executable:
250 * FILTER_ENV=3 dali-demo // LogLevel Verbose, Trace using default
251 * FILTER_ENV=1,true dali-demo // LogLevel Concise, Trace ON
252 * FILTER_ENV=2,false dali-demo // LogLevel General, Trace OFF
253 * FILTER_ENV=0,true dali-demo // LogLevel NoLogging, Trace ON
256 static Filter* New(LogLevel level, bool trace, const char * environmentVariableName );
259 * Enable trace on all filters.
261 void EnableGlobalTrace();
264 * Disable trace on all filters.
266 void DisableGlobalTrace();
272 * @param[in] level - the highest log level.
273 * @param[in] trace - whether this filter allows tracing.
275 Filter(LogLevel level, bool trace) : mLoggingLevel(level), mTraceEnabled(trace), mNesting(0) {}
277 static FilterList* GetActiveFilters();
280 // High level filters. If these filters are too broad for your current requirement, then
281 // you can add a filter to your own class or source file. If you do, use Filter::New()
282 // to tell this class about it.
284 static Filter *gRender;
285 static Filter *gResource;
286 static Filter *gGLResource;
287 static Filter *gObject;
288 static Filter *gImage;
289 static Filter *gModel;
290 static Filter *gNode;
291 static Filter *gElement;
292 static Filter *gActor;
293 static Filter *gShader;
296 LogLevel mLoggingLevel;
304 #define DALI_LOG_FILTER_SET_LEVEL(filter, level) filter->SetLogLevel(level)
305 #define DALI_LOG_FILTER_ENABLE_TRACE(filter) filter->EnableTrace()
306 #define DALI_LOG_FILTER_DISABLE_TRACE(filter) filter->DisableTrace()
310 #define DALI_LOG_FILTER_SET_LEVEL(filter, level)
311 #define DALI_LOG_FILTER_ENABLE_TRACE(filter)
312 #define DALI_LOG_FILTER_DISABLE_TRACE(filter)
316 /********************************************************************************
317 * General Logging macros *
318 ********************************************************************************/
322 #define DALI_LOG_INFO(filter, level, format, args...) \
323 if(filter && filter->IsEnabledFor(level)) { filter->Log(level, format, ## args); }
325 #define DALI_LOG_STREAM( filter, level, stream ) \
326 if(filter && filter->IsEnabledFor(level)) \
328 std::ostringstream o; \
329 o << stream << std::endl; \
330 filter->Log(level, "%s", o.str().c_str()); \
333 #else // DEBUG_ENABLED
335 #define DALI_LOG_INFO(filter, level, format, args...)
336 #define DALI_LOG_STREAM( filter, level, stream )
338 #endif // DEBUG_ENABLED
341 /********************************************************************************
343 ********************************************************************************/
346 * These macros allow the instrumentation of methods. These translate into calls
347 * to LogMessage(DebugInfo).
352 class DALI_CORE_API TraceObj
355 TraceObj(Filter* filter, const char* fmt, ...);
359 std::string mMessage;
364 #define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...) \
365 Dali::Integration::Log::TraceObj debugTraceObj(filter, "%s: " format, __PRETTY_FUNCTION__, ## args)
367 #define DALI_LOG_TRACE_METHOD(filter) \
368 Dali::Integration::Log::TraceObj debugTraceObj(filter, __PRETTY_FUNCTION__)
371 #else // DEBUG_ENABLED
373 #define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...)
374 #define DALI_LOG_TRACE_METHOD(filter)
379 /********************************************************************************
380 * Extra object debug *
381 ********************************************************************************/
386 * Warning, this macro changes the current scope, so should usually be put at the
387 * end of the class definition.
389 * Suggest that the value is usually set to the object's name.
390 * Warning - this will increase the size of the object for a debug build.
392 #define DALI_LOG_OBJECT_STRING_DECLARATION \
394 std::string mDebugString;
397 * Print all the actor tree names
399 #define DALI_LOG_ACTOR_TREE( node ) { \
400 std::stringstream branch; \
401 Node* tempNode = node; \
402 while( tempNode ) { \
403 branch << "<" << tempNode->mDebugString << ">::"; \
404 tempNode = tempNode->GetParent(); \
406 DALI_LOG_ERROR_NOFN("Actor tree: %s\n", branch.str().c_str()); \
410 * Allows one object to set another object's debug string
412 #define DALI_LOG_SET_OBJECT_STRING(object, string) (object->mDebugString = string)
415 * Allows one object to set another object's std::string easily
417 #define DALI_LOG_FMT_OBJECT_STRING(object, fmt, args...) (object->mDebugString = FormatToString(fmt, ## args))
420 * Allows one object to get another object's debug string
422 #define DALI_LOG_GET_OBJECT_STRING(object) (object->mDebugString)
425 * Get the C string (for use in formatted logging)
427 #define DALI_LOG_GET_OBJECT_C_STR(object) (object->mDebugString.c_str())
430 * Filtered logging of the object's debug string
432 #define DALI_LOG_OBJECT(filter, object) DALI_LOG_INFO(filter, Debug::General, object->mDebugString)
435 #else // DEBUG_ENABLED
437 #define DALI_LOG_OBJECT_STRING_DECLARATION
438 #define DALI_LOG_ACTOR_TREE(node)
439 #define DALI_LOG_SET_OBJECT_STRING(object, string)
440 #define DALI_LOG_FMT_OBJECT_STRING(object, fmt, args...)
441 #define DALI_LOG_GET_OBJECT_STRING(object)
442 #define DALI_LOG_GET_OBJECT_C_STR(object) ""
443 #define DALI_LOG_OBJECT(filter, object)
447 /********************************************************************************
448 * Time instrumentation *
449 ********************************************************************************/
451 #if defined(DEBUG_ENABLED)
453 void GetNanoseconds( uint64_t& timeInNanoseconds );
455 #define DALI_LOG_TIMER_START( timeVariable ) \
456 uint64_t timeVariable##1; \
457 Debug::GetNanoseconds( timeVariable##1 );
459 #define DALI_LOG_TIMER_END( timeVariable, filter, level, preString) \
460 uint64_t timeVariable##2; \
461 Debug::GetNanoseconds( timeVariable##2 ); \
462 DALI_LOG_INFO( filter, level, preString " %ld uSec\n", ((timeVariable##2-timeVariable##1)/1000));
464 #else // DEBUG_ENABLED
466 #define DALI_LOG_TIMER_START( timeVariable )
467 #define DALI_LOG_TIMER_END( timeVariable, filter, level, preString)
476 #endif // __DALI_INTEGRATION_DEBUG_H__