2 * Copyright (c) 2017 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;
57 * Generic function to print out any 2-Dimensional array
58 * @param[in] data pointer to the source data stored as float[rows][cols]
59 * @param[in] rows number of rows in 2D array
60 * @param[in] cols number of columns in 2D array
61 * @param[in] precision - the precision to write the float data.
62 * @param[in] indent - the indent level to use.
63 * @return string - the text representation of the 2D array
65 std::string Array2DToString(const float *data, unsigned int rows, unsigned int cols, size_t precision, size_t indent)
67 std::ostringstream oss;
69 std::ios_base::fmtflags mask = oss.flags();
70 mask &= ~std::ios_base::scientific;
71 mask |= std::ios_base::fixed;
73 for(unsigned int rowIdx = 0; rowIdx < rows; rowIdx++)
75 oss << std::setw(indent) << std::setfill(' ') << ' ' << "[ ";
76 oss << std::setfill(' ') << std::setprecision(precision) << std::right << std::setiosflags(mask);
78 for(unsigned int colIdx = 0; colIdx < cols; colIdx++)
80 oss << std::setw(precision + 6) << (*data++) << ' ';
83 oss << ']' << std::endl;
97 thread_local LogFunction gthreadLocalLogFunction = NULL;
99 /* Forward declarations */
100 std::string FormatToString(const char *format, ...);
101 std::string ArgListToString(const char *format, va_list args);
103 void LogMessage(DebugPriority priority, const char* format, ...)
105 if ( !gthreadLocalLogFunction )
111 va_start(arg, format);
112 std::string message = ArgListToString(format, arg);
115 gthreadLocalLogFunction(priority,message);
118 void InstallLogFunction(const LogFunction& logFunction)
120 // TLS stores a pointer to an object.
121 // It needs to be allocated on the heap, because TLS will destroy it when the thread exits.
123 gthreadLocalLogFunction = logFunction;
126 void UninstallLogFunction()
128 gthreadLocalLogFunction = NULL;
133 /*Change false to true if trace is needed but don't commit to codeline*/
134 Filter* Filter::gRender = Filter::New(Debug::Concise, false, "LOG_RENDER");
135 Filter* Filter::gResource = Filter::New(Debug::Concise, false, "LOG_RESOURCE");
136 Filter* Filter::gGLResource = Filter::New(Debug::Concise, false, "LOG_GL_RESOURCE");
137 Filter* Filter::gObject = NULL;
138 Filter* Filter::gImage = Filter::New(Debug::Concise, false, "LOG_IMAGE");
139 Filter* Filter::gModel = Filter::New(Debug::Concise, false, "LOG_MODEL");
140 Filter* Filter::gNode = NULL;
141 Filter* Filter::gElement = NULL;
142 Filter* Filter::gActor = Filter::New(Debug::Concise, false, "LOG_ACTOR");
143 Filter* Filter::gShader = Filter::New(Debug::Concise, false, "LOG_SHADER");
145 Filter::FilterList* Filter::GetActiveFilters()
147 static Filter::FilterList* activeFilters = new FilterList;
148 return activeFilters;
151 Filter* Filter::New( LogLevel level, bool trace, const char * environmentVariableName )
153 char * environmentVariableValue = getenv( environmentVariableName );
154 if ( environmentVariableValue )
156 unsigned int envLevel(0);
157 char envTraceString(0);
158 sscanf( environmentVariableValue, "%u,%c", &envLevel, &envTraceString );
160 if ( envLevel > Verbose )
164 level = LogLevel( envLevel );
166 // Just use 'f' and 't' as it's faster than doing full string comparisons
167 if ( envTraceString == 't' )
171 else if ( envTraceString == 'f' )
177 Filter* filter = new Filter(level, trace);
179 GetActiveFilters()->push_back(filter);
184 * Enable trace on all filters.
186 void Filter::EnableGlobalTrace()
188 for(FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++)
190 (*iter)->EnableTrace();
195 * Disable trace on all filters.
197 void Filter::DisableGlobalTrace()
199 for(FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++)
201 (*iter)->DisableTrace();
206 void Filter::Log(LogLevel level, const char* format, ...)
208 if(level <= mLoggingLevel)
211 va_start(arg, format);
216 int numChars = asprintf( &buffer, " %-*c %s", mNesting, ':', format );
217 if( numChars >= 0 ) // No error
219 std::string message = ArgListToString( buffer, arg );
220 LogMessage( DebugInfo, message.c_str() );
226 std::string message = ArgListToString( format, arg );
227 LogMessage( DebugInfo, message.c_str() );
234 TraceObj::TraceObj(Filter* filter, const char*format, ...) : mFilter(filter)
236 if(mFilter && mFilter->IsTraceEnabled())
239 va_start(arg, format);
240 mMessage = ArgListToString(format, arg);
243 LogMessage(DebugInfo, "Entr%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
248 TraceObj::~TraceObj()
250 if(mFilter && mFilter->IsTraceEnabled())
252 if (mFilter->mNesting)
256 LogMessage(DebugInfo, "Exit%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
260 #endif // DEBUG_ENABLED
263 std::string ArgListToString(const char *format, va_list args)
265 std::string str; // empty string
269 int err = vasprintf(&buffer, format, args);
270 if(err >= 0) // No error
279 std::string FormatToString(const char *format, ...)
282 va_start(arg, format);
283 std::string s = ArgListToString(format, arg);
288 std::string ColorToString(const Vector4& color)
290 std::ostringstream oss;
291 oss << "<R:" << color.r << " G:" << color.g << " B:" << color.b << " A:" << color.a << ">";
295 std::string Vector4ToString(const Vector4& v, size_t precision, size_t indent)
297 std::ostringstream oss;
298 oss << std::setw(indent+3) << std::setfill(' ') << std::setprecision(precision) << std::right;
299 oss << "<X:" << std::setw(precision+4) << v.x
300 << " Y:" << std::setw(precision+4) << v.y
301 << " Z:" << std::setw(precision+4) << v.z
302 << " W:" << std::setw(precision+4) << v.w << ">";
306 std::string Vector3ToString(const Vector3& v, size_t precision, size_t indent)
308 std::ostringstream oss;
309 oss << std::setw(indent+3) << std::setfill(' ') << std::setprecision(precision) << std::right << std::setiosflags(std::ios_base::fixed);
310 oss << "<X:" << std::setw(precision+4) << v.x
311 << " Y:" << std::setw(precision+4) << v.y
312 << " Z:" << std::setw(precision+4) << v.z << ">";
316 std::string QuaternionToString(const Quaternion& q, size_t precision, size_t indent)
318 std::ostringstream oss;
322 q.ToAxisAngle(axis, angle);
324 oss << std::setw(indent+3) << std::setfill(' ') << std::setprecision(precision) << std::right;
325 oss << "<A:" << std::setw(precision+4) << Degree( angle ).degree << ", " << Vector3ToString(axis, precision, 0) << ">";
330 std::string Matrix3ToString(const Matrix3& m, size_t precision, size_t indent)
332 return Array2DToString(m.AsFloat(), 3, 3, precision, indent);
335 std::string MatrixToString(const Matrix& m, size_t precision, size_t indent)
337 return Array2DToString(m.AsFloat(), 4, 4, precision, indent);
340 void GetNanoseconds( uint64_t& timeInNanoseconds )
343 clock_gettime( CLOCK_MONOTONIC, &timeSpec );
345 // Convert all values to uint64_t to match our return type
346 timeInNanoseconds = ( static_cast< uint64_t >( timeSpec.tv_sec ) * NANOSECONDS_PER_SECOND ) + static_cast< uint64_t >( timeSpec.tv_nsec );
351 } // namespace Integration