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/internal/event/common/thread-local-storage.h>
32 #include <dali/public-api/common/constants.h>
33 #include <dali/public-api/math/matrix.h>
34 #include <dali/public-api/math/matrix3.h>
35 #include <dali/public-api/math/quaternion.h>
36 #include <dali/public-api/math/vector3.h>
37 #include <dali/public-api/math/vector4.h>
43 // Fake globals for gdb typedefs
44 Dali::DebugPropertyValueArray gValueArray;
45 Dali::DebugPropertyValueMap gValueMap;
49 namespace // unnamed namespace
51 const uint64_t NANOSECONDS_PER_SECOND = 1e+9;
59 thread_local LogFunction gthreadLocalLogFunction = nullptr;
61 /* Forward declarations */
62 std::string FormatToString(const char* format, ...);
63 std::string ArgListToString(const char* format, va_list args);
65 void LogMessage(DebugPriority priority, const char* format, ...)
67 if(!gthreadLocalLogFunction)
73 va_start(arg, format);
74 std::string message = ArgListToString(format, arg);
77 gthreadLocalLogFunction(priority, message);
80 void InstallLogFunction(const LogFunction& logFunction)
82 // TLS stores a pointer to an object.
83 // It needs to be allocated on the heap, because TLS will destroy it when the thread exits.
85 gthreadLocalLogFunction = logFunction;
88 void UninstallLogFunction()
90 gthreadLocalLogFunction = nullptr;
95 /*Change false to true if trace is needed but don't commit to codeline*/
96 Filter* Filter::gRender = Filter::New(Debug::Concise, false, "LOG_RENDER");
97 Filter* Filter::gResource = Filter::New(Debug::Concise, false, "LOG_RESOURCE");
98 Filter* Filter::gGLResource = Filter::New(Debug::Concise, false, "LOG_GL_RESOURCE");
99 Filter* Filter::gObject = nullptr;
100 Filter* Filter::gImage = Filter::New(Debug::Concise, false, "LOG_IMAGE");
101 Filter* Filter::gModel = Filter::New(Debug::Concise, false, "LOG_MODEL");
102 Filter* Filter::gNode = nullptr;
103 Filter* Filter::gElement = nullptr;
104 Filter* Filter::gActor = Filter::New(Debug::Concise, false, "LOG_ACTOR");
105 Filter* Filter::gShader = Filter::New(Debug::Concise, false, "LOG_SHADER");
107 Filter::FilterList* Filter::GetActiveFilters()
109 static Filter::FilterList* activeFilters = new FilterList;
110 return activeFilters;
113 Filter* Filter::New(LogLevel level, bool trace, const char* environmentVariableName)
115 char* environmentVariableValue = getenv(environmentVariableName);
116 if(environmentVariableValue)
118 unsigned int envLevel(0);
119 char envTraceString(0);
120 sscanf(environmentVariableValue, "%u,%c", &envLevel, &envTraceString);
122 if(envLevel > Verbose)
126 level = LogLevel(envLevel);
128 // Just use 'f' and 't' as it's faster than doing full string comparisons
129 if(envTraceString == 't')
133 else if(envTraceString == 'f')
139 Filter* filter = new Filter(level, trace);
141 GetActiveFilters()->push_back(filter);
146 * Enable trace on all filters.
148 void Filter::EnableGlobalTrace()
150 for(FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++)
152 (*iter)->EnableTrace();
157 * Disable trace on all filters.
159 void Filter::DisableGlobalTrace()
161 for(FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++)
163 (*iter)->DisableTrace();
167 void Filter::SetGlobalLogLevel(LogLevel level)
169 for(FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++)
171 (*iter)->SetLogLevel(level);
175 void Filter::Log(LogLevel level, const char* format, ...)
177 if(level <= mLoggingLevel)
180 va_start(arg, format);
184 char* buffer = nullptr;
185 int numChars = asprintf(&buffer, " %-*c %s", mNesting, ':', format);
186 if(numChars >= 0) // No error
188 std::string message = ArgListToString(buffer, arg);
189 LogMessage(DebugInfo, message.c_str());
195 std::string message = ArgListToString(format, arg);
196 LogMessage(DebugInfo, message.c_str());
202 TraceObj::TraceObj(Filter* filter, const char* format, ...)
205 if(mFilter && mFilter->IsTraceEnabled())
208 va_start(arg, format);
209 mMessage = ArgListToString(format, arg);
212 LogMessage(DebugInfo, "Entr%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
217 TraceObj::~TraceObj()
219 if(mFilter && mFilter->IsTraceEnabled())
221 if(mFilter->mNesting)
225 LogMessage(DebugInfo, "Exit%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
229 #endif // DEBUG_ENABLED
231 std::string ArgListToString(const char* format, va_list args)
233 std::string str; // empty string
234 if(format != nullptr)
236 char* buffer = nullptr;
237 int err = vasprintf(&buffer, format, args);
238 if(err >= 0) // No error
247 std::string FormatToString(const char* format, ...)
250 va_start(arg, format);
251 std::string s = ArgListToString(format, arg);
256 void GetNanoseconds(uint64_t& timeInNanoseconds)
259 clock_gettime(CLOCK_MONOTONIC, &timeSpec);
261 // Convert all values to uint64_t to match our return type
262 timeInNanoseconds = (static_cast<uint64_t>(timeSpec.tv_sec) * NANOSECONDS_PER_SECOND) + static_cast<uint64_t>(timeSpec.tv_nsec);
267 } // namespace Integration