2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/integration-api/debug.h>
31 #include <dali/public-api/common/constants.h>
32 #include <dali/public-api/math/matrix3.h>
33 #include <dali/public-api/math/matrix.h>
34 #include <dali/public-api/math/vector3.h>
35 #include <dali/public-api/math/vector4.h>
36 #include <dali/public-api/math/quaternion.h>
37 #include <dali/internal/event/common/thread-local-storage.h>
44 // Fake globals for gdb typedefs
45 Dali::DebugPropertyValueArray gValueArray;
46 Dali::DebugPropertyValueMap gValueMap;
51 namespace // unnamed namespace
54 const uint64_t NANOSECONDS_PER_SECOND = 1e+9;
64 thread_local LogFunction gthreadLocalLogFunction = NULL;
66 /* Forward declarations */
67 std::string FormatToString(const char *format, ...);
68 std::string ArgListToString(const char *format, va_list args);
70 void LogMessage(DebugPriority priority, const char* format, ...)
72 if ( !gthreadLocalLogFunction )
78 va_start(arg, format);
79 std::string message = ArgListToString(format, arg);
82 gthreadLocalLogFunction(priority,message);
85 void InstallLogFunction(const LogFunction& logFunction)
87 // TLS stores a pointer to an object.
88 // It needs to be allocated on the heap, because TLS will destroy it when the thread exits.
90 gthreadLocalLogFunction = logFunction;
93 void UninstallLogFunction()
95 gthreadLocalLogFunction = NULL;
100 /*Change false to true if trace is needed but don't commit to codeline*/
101 Filter* Filter::gRender = Filter::New(Debug::Concise, false, "LOG_RENDER");
102 Filter* Filter::gResource = Filter::New(Debug::Concise, false, "LOG_RESOURCE");
103 Filter* Filter::gGLResource = Filter::New(Debug::Concise, false, "LOG_GL_RESOURCE");
104 Filter* Filter::gObject = NULL;
105 Filter* Filter::gImage = Filter::New(Debug::Concise, false, "LOG_IMAGE");
106 Filter* Filter::gModel = Filter::New(Debug::Concise, false, "LOG_MODEL");
107 Filter* Filter::gNode = NULL;
108 Filter* Filter::gElement = NULL;
109 Filter* Filter::gActor = Filter::New(Debug::Concise, false, "LOG_ACTOR");
110 Filter* Filter::gShader = Filter::New(Debug::Concise, false, "LOG_SHADER");
112 Filter::FilterList* Filter::GetActiveFilters()
114 static Filter::FilterList* activeFilters = new FilterList;
115 return activeFilters;
118 Filter* Filter::New( LogLevel level, bool trace, const char * environmentVariableName )
120 char * environmentVariableValue = getenv( environmentVariableName );
121 if ( environmentVariableValue )
123 unsigned int envLevel(0);
124 char envTraceString(0);
125 sscanf( environmentVariableValue, "%u,%c", &envLevel, &envTraceString );
127 if ( envLevel > Verbose )
131 level = LogLevel( envLevel );
133 // Just use 'f' and 't' as it's faster than doing full string comparisons
134 if ( envTraceString == 't' )
138 else if ( envTraceString == 'f' )
144 Filter* filter = new Filter(level, trace);
146 GetActiveFilters()->push_back(filter);
151 * Enable trace on all filters.
153 void Filter::EnableGlobalTrace()
155 for(FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++)
157 (*iter)->EnableTrace();
162 * Disable trace on all filters.
164 void Filter::DisableGlobalTrace()
166 for(FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++)
168 (*iter)->DisableTrace();
173 void Filter::Log(LogLevel level, const char* format, ...)
175 if(level <= mLoggingLevel)
178 va_start(arg, format);
183 int numChars = asprintf( &buffer, " %-*c %s", mNesting, ':', format );
184 if( numChars >= 0 ) // No error
186 std::string message = ArgListToString( buffer, arg );
187 LogMessage( DebugInfo, message.c_str() );
193 std::string message = ArgListToString( format, arg );
194 LogMessage( DebugInfo, message.c_str() );
201 TraceObj::TraceObj(Filter* filter, const char*format, ...) : mFilter(filter)
203 if(mFilter && mFilter->IsTraceEnabled())
206 va_start(arg, format);
207 mMessage = ArgListToString(format, arg);
210 LogMessage(DebugInfo, "Entr%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
215 TraceObj::~TraceObj()
217 if(mFilter && mFilter->IsTraceEnabled())
219 if (mFilter->mNesting)
223 LogMessage(DebugInfo, "Exit%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
227 #endif // DEBUG_ENABLED
230 std::string ArgListToString(const char *format, va_list args)
232 std::string str; // empty string
236 int err = vasprintf(&buffer, format, args);
237 if(err >= 0) // No error
246 std::string FormatToString(const char *format, ...)
249 va_start(arg, format);
250 std::string s = ArgListToString(format, arg);
255 void GetNanoseconds( uint64_t& timeInNanoseconds )
258 clock_gettime( CLOCK_MONOTONIC, &timeSpec );
260 // Convert all values to uint64_t to match our return type
261 timeInNanoseconds = ( static_cast< uint64_t >( timeSpec.tv_sec ) * NANOSECONDS_PER_SECOND ) + static_cast< uint64_t >( timeSpec.tv_nsec );
266 } // namespace Integration