Merge changes I8f46f597,I74e17e92 into devel/master
[platform/core/uifw/dali-adaptor.git] / adaptors / base / performance-logging / performance-server.cpp
index 03202aa..d6e68fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
 // CLASS HEADER
 #include "performance-server.h"
 
+// EXTERNAL INCLUDES
+#include <dali/integration-api/platform-abstraction.h>
+
 // INTERNAL INCLUDES
 #include <base/environment-options.h>
+#include <base/time-service.h>
 
 namespace Dali
 {
@@ -30,186 +34,204 @@ namespace Internal
 namespace Adaptor
 {
 
-#define TIME_FMT "%0.2f ms" // 2 decimal places, e.g. 5.34 ms
-#define TOTAL_TIME_FMT "%0.1f secs" // 1 decimal place, e.g. 4.5 seconds
-
-
 namespace
 {
-const unsigned int DEFAULT_LOG_FREQUENCEY = 2;        ///< default log frequency = 2
-const unsigned int MILLISECONDS_PER_SECOND = 1000;    ///< 1000 milliseconds per second
-const unsigned int MICROSECONDS_PER_SECOND = 1000000; ///< 1000000 microseconds per second
-}
-
+const unsigned int NANOSECONDS_PER_MICROSECOND = 1000u;
+const float        MICROSECONDS_TO_SECOND = 1e-6;
+} // unnamed namespace
 
 PerformanceServer::PerformanceServer( AdaptorInternalServices& adaptorServices,
                                       const EnvironmentOptions& environmentOptions)
-:mLoggingEnabled( false),
- mLogFunctionInstalled( false ),
- mLogFrequencyMicroseconds( 0),
- mPlatformAbstraction( adaptorServices.GetPlatformAbstractionInterface() ),
- mEnvironmentOptions(environmentOptions),
- mKernelTrace( adaptorServices.GetKernelTraceInterface() )
+: mEnvironmentOptions( environmentOptions ),
+  mKernelTrace( adaptorServices.GetKernelTraceInterface() ),
+  mSystemTrace( adaptorServices.GetSystemTraceInterface() ),
+  mLogMutex(),
+#if defined(NETWORK_LOGGING_ENABLED)
+  mNetworkServer( adaptorServices, environmentOptions ),
+  mNetworkControlEnabled( mEnvironmentOptions.GetNetworkControlMode()),
+#endif
+  mStatContextManager( *this ),
+  mStatisticsLogBitmask( 0 ),
+  mPerformanceOutputBitmask( 0 ),
+  mLoggingEnabled( false ),
+  mLogFunctionInstalled( false )
 {
-  SetLogging( mEnvironmentOptions.GetPerformanceLoggingLevel(), mEnvironmentOptions.GetFrameRateLoggingFrequency());
+  SetLogging( mEnvironmentOptions.GetPerformanceStatsLoggingOptions(),
+              mEnvironmentOptions.GetPerformanceTimeStampOutput(),
+              mEnvironmentOptions.GetPerformanceStatsLoggingFrequency());
+
+#if defined(NETWORK_LOGGING_ENABLED)
+  if( mNetworkControlEnabled )
+  {
+    mLoggingEnabled  = true;
+    mNetworkServer.Start();
+  }
+#endif
 }
 
 PerformanceServer::~PerformanceServer()
 {
+#if defined(NETWORK_LOGGING_ENABLED)
+  if( mNetworkControlEnabled )
+  {
+    mNetworkServer.Stop();
+  }
+#endif
+
   if( mLogFunctionInstalled )
   {
     mEnvironmentOptions.UnInstallLogFunction();
   }
 }
-void PerformanceServer::SetLogging( unsigned int level, unsigned int interval)
+
+void PerformanceServer::SetLogging( unsigned int statisticsLogOptions,
+                                    unsigned int timeStampOutput,
+                                    unsigned int logFrequency )
 {
-  if( level == 0)
+  mStatisticsLogBitmask = statisticsLogOptions;
+  mPerformanceOutputBitmask = timeStampOutput;
+
+  mStatContextManager.SetLoggingLevel( mStatisticsLogBitmask, logFrequency);
+
+  if( ( mStatisticsLogBitmask == 0) && ( mPerformanceOutputBitmask == 0 ))
   {
     mLoggingEnabled = false;
-    return;
   }
-  mLogLevel = level;
-
-  mLogFrequencyMicroseconds = interval * MICROSECONDS_PER_SECOND;
-
-  if( mLogFrequencyMicroseconds == 0 )
+  else
   {
-    mLogFrequencyMicroseconds = DEFAULT_LOG_FREQUENCEY * MICROSECONDS_PER_SECOND;
+    mLoggingEnabled = true;
   }
-  mLoggingEnabled = true;
+}
+
+void PerformanceServer::SetLoggingFrequency( unsigned int logFrequency, ContextId contextId )
+{
+  mStatContextManager.SetLoggingFrequency( logFrequency, contextId );
+}
+
+void PerformanceServer::EnableLogging( bool enable, ContextId contextId )
+{
+  mStatContextManager.EnableLogging( enable, contextId );
+}
+
+PerformanceInterface::ContextId PerformanceServer::AddContext( const char* name )
+{
+  // for adding custom contexts
+  return mStatContextManager.AddContext( name, PerformanceMarker::CUSTOM_EVENTS );
+}
 
+void PerformanceServer::RemoveContext( ContextId contextId )
+{
+  mStatContextManager.RemoveContext( contextId );
 }
 
-void PerformanceServer::AddMarker( PerformanceMarker::MarkerType markerType )
+void PerformanceServer::AddMarker( MarkerType markerType, ContextId contextId )
 {
+  // called only for custom markers
+
   if( !mLoggingEnabled )
   {
     return;
   }
 
-  unsigned int seconds(0);
-  unsigned int microseconds(0);
+  // Get the time stamp
+  uint64_t timeStamp = 0;
+  TimeService::GetNanoseconds( timeStamp );
+  timeStamp /= NANOSECONDS_PER_MICROSECOND; // Convert to microseconds
+
+  // Create a marker
+  PerformanceMarker marker( markerType, FrameTimeStamp( 0, timeStamp ) );
 
-  // get the time
-  mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
+  // get the marker description for this context, e.g SIZE_NEGOTIATION_START
+  const char* const description = mStatContextManager.GetMarkerDescription( markerType, contextId );
 
-  // create a marker
-  PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ));
+  // log it
+  LogMarker( marker, description );
 
-  AddMarkerToLog( marker );
+  // Add custom marker to statistics context manager
+  mStatContextManager.AddCustomMarker( marker, contextId );
 }
 
-void PerformanceServer::AddMarkerToLog( PerformanceMarker marker )
+void PerformanceServer::AddMarker( MarkerType markerType )
 {
-  // Add Marker can be called from any thread
-  boost::mutex::scoped_lock sharedDatalock( mDataMutex );
+  // called only for internal markers
 
-  // store the marker
-  mMarkers.PushBack( marker );
-
-  if( mLogLevel & LOG_EVENTS_TO_KERNEL )
+  if( !mLoggingEnabled )
   {
-    mKernelTrace.Trace(marker.GetName());
+    return;
   }
 
-  // only log on the v-sync thread, so we have less impact on update/render
-  if( marker.GetType() != PerformanceMarker::V_SYNC )
+  if( markerType == VSYNC )
   {
-    return;
+    // make sure log function is installed, note this will be called only from v-sync thread
+    // if the v-sync thread has already installed one, it won't make any difference.
+    if( ! mLogFunctionInstalled )
+    {
+      mEnvironmentOptions.InstallLogFunction();
+      mLogFunctionInstalled = true;
+    }
   }
 
-  // log out every mLogFrequency.
-  // check difference between first and last frame
-  unsigned int microseconds = PerformanceMarker::MicrosecondDiff( mMarkers[0], marker );
+  // Get the time
+  uint64_t timeStamp = 0;
+  TimeService::GetNanoseconds( timeStamp );
+  timeStamp /= NANOSECONDS_PER_MICROSECOND; // Convert to microseconds
 
-  if( microseconds  >=  mLogFrequencyMicroseconds )
-  {
-    LogMarkers( );
-    mMarkers.Clear();
+  // Create a marker
+  PerformanceMarker marker( markerType, FrameTimeStamp( 0, timeStamp ) );
+
+  // log it
+  LogMarker(marker, marker.GetName() );
+
+  // Add internal marker to statistics context manager
+  mStatContextManager.AddInternalMarker( marker );
 
-    // reset data for update / render statistics
-    mUpdateStats.Reset();
-    mRenderStats.Reset();
-    mEventStats.Reset();
-  }
 }
 
-void PerformanceServer::LogMarker(const char* name, const FrameTimeStats& frameStats)
+void PerformanceServer::LogContextStatistics( const char* const text )
 {
-  // make sure log function is installed, note this will be called only from v-sync thread
-  // if the v-sync thread has already installed one, it won't make any difference.
-  if(! mLogFunctionInstalled )
-  {
-    mEnvironmentOptions.InstallLogFunction();
-    mLogFunctionInstalled = true;
-  }
-
-  // this will always log regardless of debug / release mode
-  Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo,
-                                    "%s , min " TIME_FMT ", max " TIME_FMT ", total (" TOTAL_TIME_FMT "), avg " TIME_FMT "\n",
-                                     name,
-                                     frameStats.GetMinTime() * MILLISECONDS_PER_SECOND,
-                                     frameStats.GetMaxTime() * MILLISECONDS_PER_SECOND,
-                                     frameStats.GetTotalTime(),
-                                     frameStats.GetRollingAverageTime() * MILLISECONDS_PER_SECOND);
+  Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, text );
 }
 
-void PerformanceServer::LogMarkers()
+void PerformanceServer::LogMarker( const PerformanceMarker& marker, const char* const description )
 {
-  // insert time stamps into a frame-time-stats object, based on type
-  for( MarkerVector::SizeType i = 0; i < mMarkers.Size(); ++i)
+#if defined(NETWORK_LOGGING_ENABLED)
+  // log to the network ( this is thread safe )
+  if( mNetworkControlEnabled )
   {
-    const PerformanceMarker& marker = mMarkers[i];
-    switch( marker.GetType() )
-    {
-      case PerformanceMarker::UPDATE_START:
-      {
-        mUpdateStats.StartTime( marker.GetTimeStamp() );
-        break;
-      }
-      case PerformanceMarker::UPDATE_END:
-      {
-        mUpdateStats.EndTime( marker.GetTimeStamp() );
-        break;
-      }
-      case PerformanceMarker::RENDER_START:
-      {
-        mRenderStats.StartTime( marker.GetTimeStamp() );
-        break;
-      }
-      case PerformanceMarker::RENDER_END:
-      {
-        mRenderStats.EndTime( marker.GetTimeStamp() );
-        break;
-      }
-      case PerformanceMarker::PROCESS_EVENTS_START:
-      {
-        mEventStats.StartTime( marker.GetTimeStamp() );
-        break;
-      }
-      case PerformanceMarker::PROCESS_EVENTS_END:
-      {
-        mEventStats.EndTime( marker.GetTimeStamp() );
-        break;
-      }
-      default:
-      {
-        break;
-      }
-    }
+    mNetworkServer.TransmitMarker( marker, description );
   }
-  if( mLogLevel & LOG_UPDATE_RENDER )
+#endif
+
+  // log to kernel trace
+  if( mPerformanceOutputBitmask & OUTPUT_KERNEL_TRACE )
   {
-    LogMarker("Update",mUpdateStats);
-    LogMarker("Render",mRenderStats);
+    // Kernel tracing implementation may not be thread safe
+    Mutex::ScopedLock lock( mLogMutex );
+    // description will be something like UPDATE_START or UPDATE_END
+    mKernelTrace.Trace( marker, description );
   }
-  if( mLogLevel & LOG_EVENT_PROCESS )
+
+  // log to system trace
+  if( mPerformanceOutputBitmask & OUTPUT_SYSTEM_TRACE )
   {
-    LogMarker("Event",mEventStats);
+    // System  tracing implementation may not be thread safe
+    Mutex::ScopedLock lock( mLogMutex );
+
+    mSystemTrace.Trace( marker, description );
   }
 
+  // log to Dali log ( this is thread safe )
+  if ( mPerformanceOutputBitmask & OUTPUT_DALI_LOG )
+  {
+    Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo,
+                                    "%.6f (seconds), %s\n",
+                                    (float)( marker.GetTimeStamp().microseconds * MICROSECONDS_TO_SECOND ),
+                                    description);
+
+  }
 }
 
+
 } // namespace Internal
 
 } // namespace Adaptor