2 * Copyright (c) 2020 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 = nullptr;
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 = nullptr;
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 = nullptr;
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 = nullptr;
108 Filter* Filter::gElement = nullptr;
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();
172 void Filter::SetGlobalLogLevel( LogLevel level )
174 for(FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++)
176 (*iter)->SetLogLevel( level );
180 void Filter::Log(LogLevel level, const char* format, ...)
182 if(level <= mLoggingLevel)
185 va_start(arg, format);
189 char *buffer = nullptr;
190 int numChars = asprintf( &buffer, " %-*c %s", mNesting, ':', format );
191 if( numChars >= 0 ) // No error
193 std::string message = ArgListToString( buffer, arg );
194 LogMessage( DebugInfo, message.c_str() );
200 std::string message = ArgListToString( format, arg );
201 LogMessage( DebugInfo, message.c_str() );
208 TraceObj::TraceObj(Filter* filter, const char*format, ...) : mFilter(filter)
210 if(mFilter && mFilter->IsTraceEnabled())
213 va_start(arg, format);
214 mMessage = ArgListToString(format, arg);
217 LogMessage(DebugInfo, "Entr%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
222 TraceObj::~TraceObj()
224 if(mFilter && mFilter->IsTraceEnabled())
226 if (mFilter->mNesting)
230 LogMessage(DebugInfo, "Exit%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
234 #endif // DEBUG_ENABLED
236 std::string ArgListToString(const char *format, va_list args)
238 std::string str; // empty string
242 int err = vasprintf(&buffer, format, args);
243 if(err >= 0) // No error
252 std::string FormatToString(const char *format, ...)
255 va_start(arg, format);
256 std::string s = ArgListToString(format, arg);
261 void GetNanoseconds( uint64_t& timeInNanoseconds )
264 clock_gettime( CLOCK_MONOTONIC, &timeSpec );
266 // Convert all values to uint64_t to match our return type
267 timeInNanoseconds = ( static_cast< uint64_t >( timeSpec.tv_sec ) * NANOSECONDS_PER_SECOND ) + static_cast< uint64_t >( timeSpec.tv_nsec );
272 } // namespace Integration