From: Umar Date: Fri, 23 Feb 2018 20:19:44 +0000 (+0000) Subject: Added Trace Functionality using Performance Server. X-Git-Tag: dali_1.3.19~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=11a3c866f91cf439f404788b088bf90036f5cd48;ds=sidebyside Added Trace Functionality using Performance Server. Change-Id: Ifef92fd13a711beb592b61786eeb8e214f6d1196 --- diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp index 0e640e7..8bb7176 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp @@ -79,6 +79,11 @@ void TestApplication::Initialize() Dali::Integration::Log::LogFunction logFunction(&TestApplication::LogMessage); Dali::Integration::Log::InstallLogFunction(logFunction); + Dali::Integration::Trace::LogContextFunction logContextFunction(&TestApplication::LogContext); + Dali::Integration::Trace::InstallLogContextFunction( logContextFunction ); + + Dali::Integration::Trace::LogContext( true, "Test" ); + mCore->SceneCreated(); } @@ -88,6 +93,18 @@ TestApplication::~TestApplication() delete mCore; } +void TestApplication::LogContext( bool start, const char* tag ) +{ + if( start ) + { + fprintf(stderr, "INFO: Trace Start: %s", tag); + } + else + { + fprintf(stderr, "INFO: Trace End: %s", tag); + } +} + void TestApplication::LogMessage(Dali::Integration::Log::DebugPriority level, std::string& message) { switch(level) diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-application.h b/automated-tests/src/dali/dali-test-suite-utils/test-application.h index 5c94252..747b488 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-application.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-application.h @@ -26,6 +26,7 @@ #include "test-render-controller.h" #include #include +#include namespace Dali { @@ -66,6 +67,7 @@ public: void Initialize(); virtual ~TestApplication(); static void LogMessage( Dali::Integration::Log::DebugPriority level, std::string& message ); + static void LogContext( bool start, const char* tag ); Dali::Integration::Core& GetCore(); TestPlatformAbstraction& GetPlatform(); TestRenderController& GetRenderController(); diff --git a/build/tizen/configure.ac b/build/tizen/configure.ac index b67b716..deedf44 100644 --- a/build/tizen/configure.ac +++ b/build/tizen/configure.ac @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Samsung Electronics Co., Ltd. +# Copyright (c) 2018 Samsung Electronics Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -88,6 +88,10 @@ if test "x$enable_debug" = "xyes"; then DALI_CFLAGS="$DALI_CFLAGS -DDEBUG_ENABLED" fi +if test "x$enable_trace" = "xyes"; then + DALI_CFLAGS="$DALI_CFLAGS -DTRACE_ENABLED" +fi + if test "x$enable_debug" = "xno" -a "x$enable_exportall" = "xno"; then DALI_CFLAGS="$DALI_CFLAGS -fvisibility=hidden -DHIDE_DALI_INTERNALS" fi @@ -143,6 +147,7 @@ Configuration ------------- Prefix: $prefix Debug Build: $enable_debug + Trace Build: $enable_trace Data Dir (Read/Write): $dataReadWriteDir Data Dir (Read Only): $dataReadOnlyDir Backtrace: $enable_backtrace diff --git a/dali/integration-api/file.list b/dali/integration-api/file.list index 3337f92..1931b6c 100644 --- a/dali/integration-api/file.list +++ b/dali/integration-api/file.list @@ -4,6 +4,7 @@ platform_abstraction_src_files = \ $(platform_abstraction_src_dir)/bitmap.cpp \ $(platform_abstraction_src_dir)/core.cpp \ $(platform_abstraction_src_dir)/debug.cpp \ + $(platform_abstraction_src_dir)/trace.cpp \ $(platform_abstraction_src_dir)/profiling.cpp \ $(platform_abstraction_src_dir)/input-options.cpp \ $(platform_abstraction_src_dir)/system-overlay.cpp \ @@ -27,6 +28,7 @@ platform_abstraction_header_files = \ $(platform_abstraction_src_dir)/core-enumerations.h \ $(platform_abstraction_src_dir)/context-notifier.h \ $(platform_abstraction_src_dir)/debug.h \ + $(platform_abstraction_src_dir)/trace.h \ $(platform_abstraction_src_dir)/profiling.h \ $(platform_abstraction_src_dir)/input-options.h \ $(platform_abstraction_src_dir)/bitmap.h \ diff --git a/dali/integration-api/trace.cpp b/dali/integration-api/trace.cpp new file mode 100644 index 0000000..b11777a --- /dev/null +++ b/dali/integration-api/trace.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Integration +{ + +namespace Trace +{ + +thread_local LogContextFunction gThreadLocalLogContextFunction = nullptr; + +void InstallLogContextFunction( const LogContextFunction& logContextFunction ) +{ + gThreadLocalLogContextFunction = logContextFunction; +} + +void LogContext( bool start, const char* tag ) +{ + if ( !gThreadLocalLogContextFunction ) + { + return; + } + gThreadLocalLogContextFunction( start, tag ); +} + +#ifdef TRACE_ENABLED + +typedef std::list FilterList; +typedef std::list::iterator FilterIter; + +namespace +{ + static FilterList* GetActiveFilters() + { + static FilterList* activeFilters = new FilterList; + return activeFilters; + } +} + +Filter* Filter::New( bool trace, const char * environmentVariableName ) +{ + char * environmentVariableValue = getenv( environmentVariableName ); + if ( environmentVariableValue ) + { + char envTraceString( 0 ); + sscanf( environmentVariableValue, "%c", &envTraceString ); + + // Just use 'f' and 't' as it's faster than doing full string comparisons + if ( envTraceString == 't' ) + { + trace = true; + } + else if ( envTraceString == 'f' ) + { + trace = false; + } + } + + Filter* filter = new Filter( trace ); + GetActiveFilters()->push_back( filter ); + return filter; +} + +/** + * Enable trace on all filters. + */ +void Filter::EnableGlobalTrace() +{ + for( FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++ ) + { + (*iter)->EnableTrace(); + } +} + +/** + * Disable trace on all filters. + */ +void Filter::DisableGlobalTrace() +{ + for( FilterIter iter = GetActiveFilters()->begin(); iter != GetActiveFilters()->end(); iter++ ) + { + (*iter)->DisableTrace(); + } +} + +/** + * Begin Trace + */ +void Filter::BeginTrace( const char* tagName ) +{ + Dali::Integration::Trace::LogContext( true, tagName ); +} + +/** + * End Trace + */ +void Filter::EndTrace( const char* tagName ) +{ + Dali::Integration::Trace::LogContext( false, tagName ); +} + +/** + * Tracer Constructor + */ +Tracer::Tracer( Filter* filter, const char* tag ) +: mTag( tag ), + mFilter( filter ) +{ + if( mFilter && mFilter->IsTraceEnabled() ) + { + mFilter->BeginTrace( mTag ); + } +} + +/** + * Tracer Destructor + */ +Tracer::~Tracer() +{ + if( mFilter && mFilter->IsTraceEnabled() ) + { + mFilter->EndTrace( mTag ); + } +} + +#endif //TRACE_ENABLED + +} // Trace + +} // Integration + +} // Dali diff --git a/dali/integration-api/trace.h b/dali/integration-api/trace.h new file mode 100644 index 0000000..804effb --- /dev/null +++ b/dali/integration-api/trace.h @@ -0,0 +1,225 @@ +#ifndef DALI_INTEGRATION_TRACE_H +#define DALI_INTEGRATION_TRACE_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Integration +{ + +namespace Trace +{ + +/** + * Used by tracing macros to log a context message + * @param start a bool to indicate start (true) or end (false) of the tracing / logging + * @param tag a unique event tag name + */ +DALI_IMPORT_API void LogContext( bool start, const char* tag ); + +/** + * typedef for the LogContextFunction function. + */ +typedef void ( *LogContextFunction )( bool start, const char* tag ); + +/** + * A LogContextFunction function has to be installed for every thread that wants to use tracing. + * This should be done by the adaptor. + * The LogContextFunction function can be different for each thread. + * @param LogContextFunction the Log Context function to install + */ +DALI_IMPORT_API void InstallLogContextFunction( const LogContextFunction& logContextFunction ); + +/******************************************************************************** + * Filter * + ********************************************************************************/ + +#ifdef TRACE_ENABLED + +/** + * The Filter object is used by the DALI_TRACE_BEGIN macro and others to determine if the tracing + * should take place, and routes the tracing via the platform abstraction's LogMessage. + * + * It provides the ability to turn tracing on or off. + * + */ +class DALI_IMPORT_API Filter +{ +public: + + /** + * Test if trace is enabled for this filter. + * @return true if trace is enabled; + */ + inline bool IsTraceEnabled() { return mTraceEnabled; } + + /** + * Enable tracing on this filter. + */ + inline void EnableTrace() { mTraceEnabled = true; } + + /** + * Disable tracing on this filter. + */ + inline void DisableTrace() { mTraceEnabled = false; } + + /** + * Create a new filter whose trace can be modified through the use of an environment variable. + * + * @param[in] trace The default trace level. If true, function tracing is on. + * @param[in] environmentVariableName The environment variable name used in order to change the trace. + * + * @info To modify trace at runtime, you should define your filter as shown below: + * + * @code + * Trace::Filter* filter = Trace::Filter::New( false, "TRACE_ENV" ); + * @endcode + * + * And to use it when running an executable: + * @code + * TRACE_ENV=1 dali-demo // Trace ON + * TRACE_ENV=0 dali-demo // Trace OFF + * @endcode + */ + static Filter* New( bool trace, const char * environmentVariableName ); + + /** + * Begin trace. + * @param[in] tagName - a unique event tag name. + */ + void BeginTrace( const char* tagName ); + + /** + * End trace. + * @param[in] tagName - a unique event tag name. + */ + void EndTrace( const char* tagName ); + + /** + * Enable trace on all filters. + */ + static void EnableGlobalTrace(); + + /** + * Disable trace on all filters. + */ + static void DisableGlobalTrace(); + +private: + + /** + * Constructor. + * @param[in] trace - whether this filter allows tracing. + */ + Filter( bool trace ) : mTraceEnabled( trace ) {} + +private: + bool mTraceEnabled; +}; + +/******************************************************************************** + * Trace Macros * + ********************************************************************************/ + +/* + * These macros allow the instrumentation of methods. + */ + +/** + * The Tracer object is used by the DALI_TRACE_SCOPE and DALI_TRACE_FUNCTION macros + * and uses filter object which in tun routes the tracing via the platform abstraction's LogMessage. + * + */ +class DALI_IMPORT_API Tracer final +{ +public: + Tracer( Filter* filter, const char* tag ); + ~Tracer(); + +public: + const char* mTag; + Filter* mFilter; +}; + +/** + * For initialization of trace filter, please use DALI_INIT_TRACE_FILTER macro i.e. DALI_INIT_TRACE_FILTER( gFilter, "TRACE_COMBINED", true ); + * To start tracing, please use DALI_TRACE_BEGIN macro i.e. DALI_TRACE_BEGIN( gFilter, "RENDERING" ); + * To end tracing, please use DALI_TRACE_END macro i.e. DALI_TRACE_END( gFilter, "RENDERING" ); + * For scoped tracing, please use DALI_TRACE_SCOPE macro i.e. DALI_TRACE_SCOPE( gFilter, "RENDERING" ); + * For function tracing, please use DALI_TRACE_FUNCTION macro i.e. DALI_TRACE_FUNCTION( gFilter ); + */ + +/** + * Initialization of trace filter + * @ref Filter::New + */ +#define DALI_INIT_TRACE_FILTER( name, environmentVariableName, enable ) \ +namespace \ +{ \ + Dali::Integration::Trace::Filter* name = Dali::Integration::Trace::Filter::New( enable, #environmentVariableName ); \ +} + +/** + * Start of tracing + */ +#define DALI_TRACE_BEGIN( filter, tag ) \ + if( filter && filter->IsTraceEnabled() ) { filter->BeginTrace( tag ); } + +/** + * End of tracing + */ +#define DALI_TRACE_END( filter, tag ) \ + if( filter && filter->IsTraceEnabled() ) { filter->EndTrace( tag ); } + +/** + * Used for function tracing. It logs tracing of the fuction from start to end. + */ +#define DALI_TRACE_FUNCTION( filter ) \ + Dali::Integration::Trace::Tracer logTraceFunction( filter, __PRETTY_FUNCTION__ ); + +/** + * Used for scope tracing. It logs tracing around a scope. + */ +#define DALI_TRACE_SCOPE( filter, tag ) \ + Dali::Integration::Trace::Tracer logTracerScope( filter, tag ); + +#else // TRACE_ENABLED + +#define DALI_INIT_TRACE_FILTER( name, tag, enable ) +#define DALI_TRACE_BEGIN( filter, tag ) +#define DALI_TRACE_END( filter, tag ) +#define DALI_TRACE_FUNCTION( filter ) +#define DALI_TRACE_SCOPE( filter, tag ) + +#endif + +} // Trace + +} // Integration + +} // Dali + +#endif // DALI_INTEGRATION_TRACE_H diff --git a/packaging/dali.spec b/packaging/dali.spec index 1be75a5..8812bae 100644 --- a/packaging/dali.spec +++ b/packaging/dali.spec @@ -149,6 +149,9 @@ LDFLAGS="${LDFLAGS:-%optflags}" ; export LDFLAGS; %if 0%{?enable_debug} --enable-debug \ %endif +%if 0%{?enable_trace} + --enable-trace \ +%endif --infodir=%{_infodir} \ --enable-rename-so=no @@ -185,6 +188,9 @@ make clean %if 0%{?enable_debug} --enable-debug \ %endif +%if 0%{?enable_trace} + --enable-trace \ +%endif --infodir=%{_infodir} \ --enable-rename-so=no