Expose custom performance timers 73/30373/13
authorKingsley Stephens <k.stephens@partner.samsung.com>
Mon, 10 Nov 2014 17:24:58 +0000 (17:24 +0000)
committerKingsley Stephens <k.stephens@partner.samsung.com>
Mon, 15 Dec 2014 10:38:19 +0000 (02:38 -0800)
Change-Id: I4e11fc2a4d82a6a2b5ea3366067ff033a76ff219

17 files changed:
adaptors/base/interfaces/performance-interface.h
adaptors/base/performance-logging/frame-time-stats.cpp
adaptors/base/performance-logging/frame-time-stats.h
adaptors/base/performance-logging/performance-marker.cpp
adaptors/base/performance-logging/performance-marker.h
adaptors/base/performance-logging/performance-server.cpp
adaptors/base/performance-logging/performance-server.h
adaptors/base/update-render-synchronization.cpp
adaptors/base/update-render-synchronization.h
adaptors/common/adaptor-impl.cpp
adaptors/common/file.list
adaptors/common/performance-logger-impl.cpp [new file with mode: 0644]
adaptors/common/performance-logger-impl.h [new file with mode: 0644]
adaptors/public-api/adaptor-framework/performance-logger.cpp [new file with mode: 0644]
adaptors/public-api/adaptor-framework/performance-logger.h [new file with mode: 0644]
adaptors/public-api/dali.h
adaptors/public-api/file.list

index 563f138..25e71fe 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include <base/performance-logging/performance-marker.h>
-
-
 namespace Dali
 {
 
@@ -40,15 +36,40 @@ class PerformanceInterface
 {
 public:
 
+  typedef unsigned short ContextId;   ///< Type to represent a context ID
+
   /**
    * bitmask of logging options
    */
   enum LogLevel
   {
     DISABLED             = 0,
-    LOG_UPDATE_RENDER    = 1 << 0, ///< Bit 0, log update and render times
-    LOG_EVENT_PROCESS    = 1 << 1, ///< Bit 1, log event process times
-    LOG_EVENTS_TO_KERNEL = 1 << 2, ///< Bit 2, log all events to kernel trace
+    ENABLED              = 1 << 0, ///< Bit 0, log all
+    LOG_UPDATE_RENDER    = 1 << 1, ///< Bit 1, log update and render times
+    LOG_EVENT_PROCESS    = 1 << 2, ///< Bit 2, log event process times
+    LOG_EVENTS_TO_KERNEL = 1 << 3  ///< Bit 3, log all events to kernel trace
+  };
+
+  /**
+   * enum for difference performance markers.
+   * Please modify the name lookup table in performance-interface.cpp
+   * file if adding new markers.
+   */
+  enum MarkerType
+  {
+    VSYNC     = 0,        ///< V-Sync
+    UPDATE_START ,        ///< Update start
+    UPDATE_END   ,        ///< Update end
+    RENDER_START ,        ///< Render start
+    RENDER_END   ,        ///< Render end
+    SWAP_START   ,        ///< SwapBuffers Start
+    SWAP_END     ,        ///< SwapBuffers End
+    PROCESS_EVENTS_START, ///< Process events start (e.g. touch event)
+    PROCESS_EVENTS_END,   ///< Process events end
+    PAUSED       ,        ///< Pause start
+    RESUME       ,        ///< Resume start
+    START        ,        ///< The start of custom tracking
+    END                   ///< The end of custom tracking
   };
 
   /**
@@ -62,11 +83,35 @@ public:
   virtual ~PerformanceInterface() {};
 
   /**
+   * Add a new context with a given name
+   *
+   * @param[in] name The name of the context
+   * @return Return the unique id for this context
+   */
+  virtual ContextId AddContext( const char* name ) = 0;
+
+  /**
+   * Remove a context from use
+   *
+   * @param[in] contextId The ID of the context to remove
+   */
+  virtual void RemoveContext( ContextId contextId ) = 0;
+
+  /**
    * Add a performance marker
    * This function can be called from ANY THREAD.
+   * The default context 0 Event/Update/Render is assumed.
    * @param markerType performance marker type
    */
-  virtual void AddMarker( PerformanceMarker::MarkerType markerType) = 0;
+  virtual void AddMarker( MarkerType markerType ) = 0;
+
+  /**
+   * Add a performance marker
+   * This function can be called from ANY THREAD.
+   * @param markerType performance marker type
+   * @param contextId The context of the marker. This must be one generated by AddContext.
+   */
+  virtual void AddMarker( MarkerType markerType, ContextId contextId ) = 0;
 
   /**
    * Set the logging level and frequency
@@ -75,6 +120,21 @@ public:
    */
   virtual void SetLogging( unsigned int level, unsigned int logFrequency) = 0;
 
+  /**
+   * Set the logging frequency
+   *
+   * @param logFrequency how often to log out in seconds
+   */
+  virtual void SetLoggingFrequency( unsigned int logFrequency, ContextId contextId ) = 0;
+
+  /**
+   * Set logging on or off for a particular context
+   *
+   * @param[in] enable Enable logging or not
+   * @param[in] contextId The id of the context to log. This must be one generated by AddContext.
+   */
+  virtual void EnableLogging( bool enable, ContextId contextId ) = 0;
+
 private:
 
   // Undefined copy constructor.
index ac1b1cb..b6f0bdb 100644 (file)
@@ -18,6 +18,8 @@
 // STRUCT HEADER
 #include "frame-time-stats.h"
 
+#include <cmath>
+
 namespace Dali
 {
 
@@ -36,6 +38,8 @@ const float ONE_OVER_MICROSECONDS_TO_SECONDS = 1.f / 1000000.f; ///< microsecond
 FrameTimeStats::FrameTimeStats()
 : mTotal( 0.f)
 {
+  mSamples.Reserve( 16 );   // Fill out a little to avoid early reallocations
+
   Reset();
 }
 
@@ -69,12 +73,13 @@ void FrameTimeStats::EndTime( const FrameTimeStamp& timeStamp )
   // frame time in seconds
   unsigned int elapsedTime = FrameTimeStamp::MicrosecondDiff( mStart, timeStamp);
 
+  mSamples.PushBack( elapsedTime );
+
   // if the min and max times haven't been set, do that now.
   if( !mMinMaxTimeSet )
   {
     mMin = elapsedTime;
     mMax = elapsedTime;
-    mAvg = elapsedTime;
     mMinMaxTimeSet = true;
   }
   else
@@ -90,10 +95,6 @@ void FrameTimeStats::EndTime( const FrameTimeStamp& timeStamp )
   }
 
   mTotal += elapsedTime;
-
-  // calculate a rolling average
-  mAvg = (elapsedTime * (1.0f - EPSILON)) + (mAvg * EPSILON);
-
 }
 
 void FrameTimeStats::Reset()
@@ -102,13 +103,8 @@ void FrameTimeStats::Reset()
   mMinMaxTimeSet = false;
   mMin = 0.f;
   mMax = 0.f;
-  mAvg = 0.f;
   mRunCount = 0;
-}
-
-float FrameTimeStats::GetRollingAverageTime() const
-{
-  return mAvg * ONE_OVER_MICROSECONDS_TO_SECONDS;
+  mSamples.Clear();
 }
 
 float FrameTimeStats::GetMaxTime() const
@@ -131,6 +127,47 @@ unsigned int FrameTimeStats::GetRunCount() const
   return mRunCount;
 }
 
+void FrameTimeStats::CalculateMean( float& meanOut, float& standardDeviationOut ) const
+{
+  if( mSamples.Size() > 0 )
+  {
+    // Mean
+    unsigned int sum = 0;
+    for( Samples::ConstIterator it = mSamples.Begin(), itEnd = mSamples.End(); it != itEnd; ++it )
+    {
+      unsigned int value = *it;
+
+      sum += value;
+    }
+
+    meanOut = static_cast<float>(sum) / mSamples.Size();
+
+    // Variance
+    float variance = 0.0f;
+    for( Samples::ConstIterator it = mSamples.Begin(), itEnd = mSamples.End(); it != itEnd; ++it )
+    {
+      unsigned int value = *it;
+
+      float difference = static_cast<float>(value) - meanOut;
+
+      variance += difference * difference;
+    }
+
+    variance /= mSamples.Size();
+
+    // Standard deviation
+    standardDeviationOut = sqrtf( variance );
+
+    meanOut *= ONE_OVER_MICROSECONDS_TO_SECONDS;
+    standardDeviationOut *= ONE_OVER_MICROSECONDS_TO_SECONDS;
+  }
+  else
+  {
+    meanOut = 0.0f;
+    standardDeviationOut = 0.0f;
+  }
+}
+
 
 } // namespace Adaptor
 
index b32816a..5022f74 100644 (file)
@@ -19,8 +19,9 @@
  */
 
 // INTERNAL INCLUDES
+#include <base/performance-logging/frame-time-stamp.h>
+#include <dali/public-api/common/dali-vector.h>
 
-#include "frame-time-stamp.h"
 
 namespace Dali
 {
@@ -66,11 +67,6 @@ struct FrameTimeStats
    void Reset();
 
    /**
-    * @return rolling average time in seconds
-    */
-   float GetRollingAverageTime() const;
-
-   /**
     * @return maximum time in seconds
     */
    float GetMaxTime() const;
@@ -90,6 +86,14 @@ struct FrameTimeStats
     */
    unsigned int GetRunCount() const;
 
+   /**
+    * Calculate the mean and standard deviation
+    *
+    * @param[out] mean The return mean value
+    * @param[out] standardDeviation The return standard deviation value
+    */
+   void CalculateMean( float& meanOut, float& standardDeviationOut ) const;
+
 private:
 
    /**
@@ -101,9 +105,11 @@ private:
      WAITING_FOR_END_TIME       ///< waiting for end time marker
    };
 
+   typedef Dali::Vector< unsigned int > Samples;
+   Samples mSamples;
+
    unsigned int mMin;                  ///< current minimum value in microseconds
    unsigned int mMax;                  ///< current maximum value in microseconds
-   unsigned int mAvg;                  ///< current average in microseconds
    unsigned int mTotal;                ///< current total in in microseconds
    unsigned int mRunCount;      ///< how many times the timer has been start / stopped
    FrameTimeStamp mStart;       ///< start time stamp, to calculate the diff
index 1367549..4e08d17 100644 (file)
@@ -27,46 +27,17 @@ namespace Internal
 namespace Adaptor
 {
 
-namespace
-{
-
-struct NamePair
-{
-  PerformanceMarker::MarkerType type;
-  const char* name;
-};
-
-const NamePair MarkerLookup[] =
-{
-    { PerformanceMarker::V_SYNC       ,        "V_SYNC"                },
-    { PerformanceMarker::UPDATE_START ,        "UPDATE_START"          },
-    { PerformanceMarker::UPDATE_END   ,        "UPDATE_END"            },
-    { PerformanceMarker::RENDER_START ,        "RENDER_START"          },
-    { PerformanceMarker::RENDER_END   ,        "RENDER_END"            },
-    { PerformanceMarker::SWAP_START   ,        "SWAP_START"            },
-    { PerformanceMarker::SWAP_END     ,        "SWAP_END"              },
-    { PerformanceMarker::PROCESS_EVENTS_START, "PROCESS_EVENT_START"   },
-    { PerformanceMarker::PROCESS_EVENTS_END,   "PROCESS_EVENT_END"     },
-    { PerformanceMarker::PAUSED       ,        "PAUSED"                },
-    { PerformanceMarker::RESUME       ,        "RESUMED"               }
-};
-}
-PerformanceMarker::PerformanceMarker( MarkerType type )
+PerformanceMarker::PerformanceMarker( PerformanceInterface::MarkerType type )
 :mType(type)
 {
 }
 
-PerformanceMarker::PerformanceMarker( MarkerType type, FrameTimeStamp frameInfo )
+PerformanceMarker::PerformanceMarker( PerformanceInterface::MarkerType type, FrameTimeStamp frameInfo )
 :mType(type),
  mTimeStamp(frameInfo)
 {
 }
 
-const char* PerformanceMarker::GetName( ) const
-{
-  return MarkerLookup[ mType ].name;
-}
-
 unsigned int PerformanceMarker::MicrosecondDiff( const PerformanceMarker& start,const PerformanceMarker& end )
 {
   return FrameTimeStamp::MicrosecondDiff( start.mTimeStamp, end.mTimeStamp );
index 5f3b096..593a401 100644 (file)
@@ -19,7 +19,8 @@
  */
 
 // INTERNAL INCLUDES
-#include "frame-time-stamp.h"
+#include <base/interfaces/performance-interface.h>
+#include <base/performance-logging/frame-time-stamp.h>
 
 namespace Dali
 {
@@ -38,37 +39,17 @@ class PerformanceMarker
 public:
 
   /**
-   * enum for difference performance markers.
-   * Please modify the name lookup table in performance-marker.cpp
-   * file if adding new markers.
-   */
-  enum MarkerType
-  {
-      V_SYNC    = 0,        ///< V-Sync
-      UPDATE_START ,        ///< Update start
-      UPDATE_END   ,        ///< Update end
-      RENDER_START ,        ///< Render start
-      RENDER_END   ,        ///< Render end
-      SWAP_START   ,        ///< SwapBuffers Start
-      SWAP_END     ,        ///< SwapBuffers End
-      PROCESS_EVENTS_START, ///< Process events start (e.g. touch event)
-      PROCESS_EVENTS_END,   ///< Process events end
-      PAUSED       ,        ///< Pause start
-      RESUME                ///< Resume start
-  };
-
-  /**
    * Constructor
    * @param type marker type
    */
-  PerformanceMarker( MarkerType type);
+  PerformanceMarker( PerformanceInterface::MarkerType type );
 
   /**
    * Constructor
    * @param type marker type
    * @param time time stamp
    */
-  PerformanceMarker(MarkerType type,  FrameTimeStamp time);
+  PerformanceMarker( PerformanceInterface::MarkerType type,  FrameTimeStamp time );
 
   /**
    * @return the time stamp
@@ -81,17 +62,12 @@ public:
   /**
    * @return the type of marker
    */
-  MarkerType GetType() const
+  PerformanceInterface::MarkerType GetType() const
   {
     return mType;
   }
 
   /**
-   * @return the name of the marker
-   */
-  const char* GetName() const;
-
-  /**
    * @param start the start marker
    * @param end the end marker
    * @return difference in microseconds between two markers
@@ -100,8 +76,8 @@ public:
 
 private:
 
-  MarkerType           mType;         ///< marker type
-  FrameTimeStamp       mTimeStamp;    ///< frame time stamp
+  PerformanceInterface::MarkerType mType;         ///< marker type
+  FrameTimeStamp mTimeStamp;                      ///< frame time stamp
 
 };
 
index 6634eec..5187387 100644 (file)
@@ -37,21 +37,33 @@ namespace Adaptor
 
 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 char* UPDATE_CONTEXT_NAME = "Update";
+const char* RENDER_CONTEXT_NAME = "Render";
+const char* EVENT_CONTEXT_NAME = "Event";
+
+} // Anonymous namespace
 
 
 PerformanceServer::PerformanceServer( AdaptorInternalServices& adaptorServices,
                                       const EnvironmentOptions& environmentOptions)
-:mLoggingEnabled( false),
- mLogFunctionInstalled( false ),
- mLogFrequencyMicroseconds( 0),
- mPlatformAbstraction( adaptorServices.GetPlatformAbstractionInterface() ),
- mEnvironmentOptions(environmentOptions),
- mKernelTrace( adaptorServices.GetKernelTraceInterface() )
+:mPlatformAbstraction( adaptorServices.GetPlatformAbstractionInterface() ),
+ mEnvironmentOptions( environmentOptions ),
+ mKernelTrace( adaptorServices.GetKernelTraceInterface() ),
+ mLogLevel( 0 ),
+ mNextContextId( 0 ),
+ mLoggingEnabled( false ),
+ mLogFunctionInstalled( false )
 {
+  // Add defaults
+  mUpdateStats = AddContext( UPDATE_CONTEXT_NAME );
+  mRenderStats = AddContext( RENDER_CONTEXT_NAME );
+  mEventStats = AddContext( EVENT_CONTEXT_NAME );
+
   SetLogging( mEnvironmentOptions.GetPerformanceLoggingLevel(), mEnvironmentOptions.GetFrameRateLoggingFrequency());
 }
 
@@ -61,101 +73,231 @@ PerformanceServer::~PerformanceServer()
   {
     mEnvironmentOptions.UnInstallLogFunction();
   }
+
+  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
+  {
+    StatContext* context = *it;
+
+    delete context;
+  }
 }
-void PerformanceServer::SetLogging( unsigned int level, unsigned int interval)
+
+void PerformanceServer::SetLogging( unsigned int level, unsigned int logFrequency)
 {
-  if( level == 0)
+  if( level == 0 )
   {
     mLoggingEnabled = false;
     return;
   }
   mLogLevel = level;
 
-  mLogFrequencyMicroseconds = interval * MICROSECONDS_PER_SECOND;
+  EnableLogging( mLogLevel & LOG_UPDATE_RENDER, mUpdateStats );
+  EnableLogging( mLogLevel & LOG_UPDATE_RENDER, mRenderStats );
+  EnableLogging( mLogLevel & LOG_EVENT_PROCESS, mEventStats );
+
+  SetLoggingFrequency( logFrequency, mUpdateStats );
+  SetLoggingFrequency( logFrequency, mRenderStats );
+  SetLoggingFrequency( logFrequency, mEventStats );
 
-  if( mLogFrequencyMicroseconds == 0 )
-  {
-    mLogFrequencyMicroseconds = DEFAULT_LOG_FREQUENCEY * MICROSECONDS_PER_SECOND;
-  }
   mLoggingEnabled = true;
+}
 
+void PerformanceServer::SetLoggingFrequency( unsigned int logFrequency, ContextId contextId )
+{
+  StatContext* context = GetContext( contextId );
+  if( context )
+  {
+    unsigned int logFrequencyMicroseconds = logFrequency * MICROSECONDS_PER_SECOND;
+
+    if( logFrequencyMicroseconds == 0 )
+    {
+      logFrequencyMicroseconds = DEFAULT_LOG_FREQUENCEY * MICROSECONDS_PER_SECOND;
+    }
+
+    context->SetLogFrequency( logFrequencyMicroseconds );
+  }
 }
 
-void PerformanceServer::AddMarker( PerformanceMarker::MarkerType markerType )
+void PerformanceServer::EnableLogging( bool enable, ContextId contextId )
 {
-  if( !mLoggingEnabled )
+  StatContext* context = GetContext( contextId );
+  if( context )
   {
-    return;
+    context->EnableLogging( enable );
   }
+}
 
-  unsigned int seconds(0);
-  unsigned int microseconds(0);
+PerformanceServer::StatContext::StatContext()
+: mName( NULL ),
+  mId( 0 ),
+  mLogFrequencyMicroseconds( DEFAULT_LOG_FREQUENCEY * MICROSECONDS_PER_SECOND ),
+  mLog( true )
+{
+}
 
-  // get the time
-  mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
+PerformanceServer::StatContext::StatContext( unsigned int id, const char* contextName )
+: mName( contextName ),
+  mId( id ),
+  mLogFrequencyMicroseconds( DEFAULT_LOG_FREQUENCEY * MICROSECONDS_PER_SECOND ),
+  mLog( true )
+{
+}
+
+PerformanceInterface::ContextId PerformanceServer::AddContext( const char* name )
+{
+  unsigned int contextId = mNextContextId++;
 
-  // create a marker
-  PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ));
+  DALI_ASSERT_DEBUG( !GetContext( contextId ) );
 
-  AddMarkerToLog( marker );
+  mStatContexts.PushBack( new StatContext( contextId, name ) );
+
+  return contextId;
 }
 
-void PerformanceServer::AddMarkerToLog( PerformanceMarker marker )
+void PerformanceServer::RemoveContext( ContextId contextId )
 {
-  // Add Marker can be called from any thread
-  boost::mutex::scoped_lock sharedDatalock( mDataMutex );
+  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
+  {
+    StatContext* context = *it;
 
-  // store the marker
-  mMarkers.PushBack( marker );
+    if( context->GetId() == contextId )
+    {
+      delete context;
 
-  if( mLogLevel & LOG_EVENTS_TO_KERNEL )
-  {
-    mKernelTrace.Trace(marker.GetName());
+      mStatContexts.Erase( it );
+      break;
+    }
   }
+}
 
-  // only log on the v-sync thread, so we have less impact on update/render
-  if( marker.GetType() != PerformanceMarker::V_SYNC )
+PerformanceServer::StatContext* PerformanceServer::GetContext( ContextId contextId )
+{
+  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
   {
-    return;
+    StatContext* context = *it;
+
+    if( context->GetId() == contextId )
+    {
+      return context;
+    }
   }
 
-  // log out every mLogFrequency.
-  // check difference between first and last frame
-  unsigned int microseconds = PerformanceMarker::MicrosecondDiff( mMarkers[0], marker );
+  return NULL;
+}
 
-  if( microseconds  >=  mLogFrequencyMicroseconds )
+void PerformanceServer::AddMarker( MarkerType markerType )
+{
+  switch( markerType )
   {
-    LogMarkers( );
-    mMarkers.Clear();
+    case VSYNC:
+    {
+      for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
+      {
+        StatContext* context = *it;
+
+        AddMarker( VSYNC, context->GetId() );
+      }
+      break;
+    }
+    case UPDATE_START:
+    {
+      AddMarker( START, mUpdateStats );
+      break;
+    }
+    case UPDATE_END:
+    {
+      AddMarker( END, mUpdateStats );
+      break;
+    }
+    case RENDER_START:
+    {
+      AddMarker( START, mRenderStats );
+      break;
+    }
+    case RENDER_END:
+    {
+      AddMarker( END, mRenderStats );
+      break;
+    }
+    case PROCESS_EVENTS_START:
+    {
+      AddMarker( START, mEventStats );
+      break;
+    }
+    case PROCESS_EVENTS_END:
+    {
+      AddMarker( END, mEventStats );
+      break;
+    }
+    default:
+    {
+      break;
+    }
+  }
+}
 
-    // reset data for update / render statistics
-    mUpdateStats.Reset();
-    mRenderStats.Reset();
-    mEventStats.Reset();
+void PerformanceServer::AddMarker( MarkerType markerType, ContextId contextId )
+{
+  if( !mLoggingEnabled )
+  {
+    return;
   }
+
+  // Get the time
+  unsigned int seconds = 0;
+  unsigned int microseconds = 0;
+  mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
+
+  // Create a marker and add it to the log
+  PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ) );
+  AddMarkerToLog( marker, contextId );
 }
 
-void PerformanceServer::LogMarker(const char* name, const FrameTimeStats& frameStats)
+void PerformanceServer::AddMarkerToLog( const PerformanceMarker& marker, ContextId contextId )
 {
-  // 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 )
+  StatContext* context = GetContext( contextId );
+  if( context )
   {
-    mEnvironmentOptions.InstallLogFunction();
-    mLogFunctionInstalled = true;
+    if( mLogLevel & LOG_EVENTS_TO_KERNEL )
+    {
+      std::stringstream ss;
+      ss << GetMarkerName( marker.GetType() ) << ":" << ( ( context->GetName() ) ? context->GetName() : "" );
+      mKernelTrace.Trace( ss.str() );
+    }
+
+    // Only log on the v-sync thread, so we have less impact on update/render
+    if( marker.GetType() == VSYNC )
+    {
+      // 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;
+      }
+    }
+
+    context->LogMarker( marker );
   }
+}
+
+void PerformanceServer::StatContext::LogMarker()
+{
+  float mean, standardDeviation;
+  mStats.CalculateMean( mean, standardDeviation );
 
   // 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);
+                                    "%s, min " TIME_FMT ", max " TIME_FMT ", total (" TOTAL_TIME_FMT "), avg " TIME_FMT ", std dev " TIME_FMT "\n",
+                                     ( mName ) ? mName : "",
+                                     mStats.GetMinTime() * MILLISECONDS_PER_SECOND,
+                                     mStats.GetMaxTime() * MILLISECONDS_PER_SECOND,
+                                     mStats.GetTotalTime(),
+                                     mean * MILLISECONDS_PER_SECOND,
+                                     standardDeviation * MILLISECONDS_PER_SECOND);
 }
 
-void PerformanceServer::LogMarkers()
+void PerformanceServer::StatContext::TimeMarkers()
 {
   // insert time stamps into a frame-time-stats object, based on type
   for( MarkerVector::SizeType i = 0; i < mMarkers.Size(); ++i)
@@ -163,34 +305,14 @@ void PerformanceServer::LogMarkers()
     const PerformanceMarker& marker = mMarkers[i];
     switch( marker.GetType() )
     {
-      case PerformanceMarker::UPDATE_START:
+      case START:
       {
-        mUpdateStats.StartTime( marker.GetTimeStamp() );
+        mStats.StartTime( marker.GetTimeStamp() );
         break;
       }
-      case PerformanceMarker::UPDATE_END:
+      case 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() );
+        mStats.EndTime( marker.GetTimeStamp() );
         break;
       }
       default:
@@ -199,16 +321,82 @@ void PerformanceServer::LogMarkers()
       }
     }
   }
-  if( mLogLevel & LOG_UPDATE_RENDER )
+
+  mMarkers.Clear();
+}
+
+const char* PerformanceServer::GetMarkerName( MarkerType type ) const
+{
+  switch( type )
   {
-    LogMarker("Update",mUpdateStats);
-    LogMarker("Render",mRenderStats);
+    case VSYNC:
+    {
+      return "VSYNC";
+    }
+
+    case START:
+    {
+      return "START";
+    }
+
+    case END:
+    {
+      return "END";
+    }
+
+    default:
+    {
+      DALI_ASSERT_DEBUG( !"Unsupported MarkerType" );
+      return "";
+    }
   }
-  if( mLogLevel & LOG_EVENT_PROCESS )
+}
+
+void PerformanceServer::StatContext::LogMarker( const PerformanceMarker& marker )
+{
+  // Add Marker can be called from any thread
+  boost::mutex::scoped_lock sharedDatalock( mDataMutex );
+
+  mMarkers.PushBack( marker );
+
+  // Only log on the v-sync thread, so we have less impact on update/render
+  if( marker.GetType() == VSYNC )
   {
-    LogMarker("Event",mEventStats);
+    // log out every mLogFrequency.
+    // check difference between first and last frame
+    unsigned int microseconds = PerformanceMarker::MicrosecondDiff( mMarkers[0], marker );
+    if( microseconds >= mLogFrequencyMicroseconds )
+    {
+      TimeMarkers();
+
+      if( mLog )
+      {
+        LogMarker();
+      }
+
+      mStats.Reset();     // reset data for statistics
+    }
   }
+}
 
+void PerformanceServer::StatContext::SetLogFrequency( unsigned int frequencyMicroseconds )
+{
+  mLogFrequencyMicroseconds = frequencyMicroseconds;
+}
+
+void PerformanceServer::StatContext::EnableLogging( bool enableLogging )
+{
+  mLog = enableLogging;
+}
+
+const char* PerformanceServer::StatContext::GetName() const
+{
+  return mName;
+}
+
+unsigned int PerformanceServer::StatContext::GetId() const
+{
+  return mId;
 }
 
 } // namespace Internal
index 2f69d9e..21f7b68 100644 (file)
@@ -22,6 +22,7 @@
 #include <base/performance-logging/frame-time-stats.h>
 #include <dali/public-api/common/dali-vector.h>
 #include <base/interfaces/adaptor-internal-services.h>
+#include <base/performance-logging/performance-marker.h>
 
 // EXTERNAL INCLUDES
 #include <boost/thread/mutex.hpp>
@@ -36,6 +37,7 @@ namespace Adaptor
 {
 
 class EnvironmentOptions;
+
 /**
  * Concrete implementation of performance interface.
  * Adaptor classes should never include this file, they
@@ -43,7 +45,6 @@ class EnvironmentOptions;
  */
 class PerformanceServer : public PerformanceInterface
 {
-
 public:
 
   /**
@@ -60,53 +61,167 @@ public:
   virtual ~PerformanceServer();
 
   /**
+   * @copydoc PerformanceLogger::AddContext()
+   */
+  virtual ContextId AddContext( const char* name );
+
+  /**
+   * @copydoc PerformanceLogger::RemoveContext()
+   */
+  virtual void RemoveContext( ContextId contextId );
+
+  /**
    * @copydoc PerformanceInterface::AddMarker()
    */
-  virtual void AddMarker( PerformanceMarker::MarkerType markerType);
+  virtual void AddMarker( MarkerType markerType );
+
+  /**
+   * @copydoc PerformanceLogger::AddMarker()
+   */
+  virtual void AddMarker( MarkerType markerType, ContextId contextId );
 
   /**
    * @copydoc PerformanceInterface::SetLogging()
    */
-  virtual void SetLogging( unsigned int level, unsigned int interval);
+  virtual void SetLogging( unsigned int level, unsigned int logFrequency );
+
+  /**
+   * @copydoc PerformanceLogger::SetLoggingFrequency()
+   */
+  virtual void SetLoggingFrequency( unsigned int logFrequency, ContextId contextId );
 
+  /**
+   * @copydoc PerformanceLogger::EnableLogging()
+   */
+  virtual void EnableLogging( bool enable, ContextId contextId );
 
 private:
 
   /**
-   * Helper
+   * Class to hold a stat context
    */
-  void AddMarkerToLog( PerformanceMarker marker );
+  class StatContext
+  {
+  public:
+
+    /**
+     * Default constructor
+     */
+    StatContext();
+
+    /**
+     * Constructor
+     *
+     * @param[in] id The ID to give the context
+     * @param[in] contextName Name of the context to print in console
+     */
+    StatContext( unsigned int id, const char* contextName );
+
+    /**
+     * Return the ID
+     *
+     * @return Return the ID
+     */
+    unsigned int GetId() const;
+
+    /**
+     * Return the context name
+     *
+     * @return Return the context name
+     */
+    const char* GetName() const;
+
+    /**
+     * Log the given marker
+     *
+     * @param[in] marker The marker to log
+     */
+    void LogMarker( const PerformanceMarker& marker );
+
+    /**
+     * Set the frequency for logging
+     *
+     * @param[in] frequencyMicroseconds The frequency to set
+     */
+    void SetLogFrequency( unsigned int frequencyMicroseconds );
+
+    /**
+     * Enable/disable logging
+     *
+     * @param[in] enableLogging Flag to spePerformancecify enabling/disabling
+     */
+    void EnableLogging( bool enableLogging );
+
+  private:
+
+    /**
+     * Helper to print to console
+     */
+    void LogMarker();
+
+    /**
+     * Accumulate timer from markers
+     */
+    void TimeMarkers();
+
+  private:
+
+    typedef Dali::Vector< PerformanceMarker > MarkerVector;
+
+    FrameTimeStats mStats;       ///< Frame time stats to accumulate
+    MarkerVector mMarkers;       ///< vector of markers
+    boost::mutex mDataMutex;     ///< mutex
+
+    const char* mName;           ///< Name of the context
+
+    unsigned int mId;            ///< The ID of the context
+
+    unsigned int mLogFrequencyMicroseconds; ///< if logging is enabled, what frequency to log out at in micro-seconds
+    bool mLog;                              ///< Whether to print the log for this context or not
+  };
 
   /**
    * Helper
    */
-  void LogMarker(const char* name, const FrameTimeStats& frameStats);
+  void AddMarkerToLog( const PerformanceMarker& marker, ContextId contextId );
 
   /**
-   * log markers out
+   * Retrieve a stat context by ID
+   *
+   * @param[in] contextId The ID of the context to retrieve
+   * @return Return the stat context if it exists or null
    */
-  void LogMarkers();
+  StatContext* GetContext( ContextId contextId );
 
-private:
+  /**
+   * Return a string representation of the marker type
+   *
+   * @param[in] type The marker type
+   * @return Return the name of the given marker
+   */
+  const char* GetMarkerName( MarkerType type ) const;
 
-  bool mLoggingEnabled:1;         ///< whether logging update / render to a log is enabled
-  bool mLogFunctionInstalled:1;   ///< whether the log function is installed
-  unsigned int mLogLevel;         ///< log level
+private:
 
-  unsigned int mLogFrequencyMicroseconds; ///< if logging is enabled, what frequency to log out at in micro-seconds
+  typedef Dali::Vector< StatContext* > StatContexts;
 
-  FrameTimeStats mUpdateStats;    ///< update time statistics
-  FrameTimeStats mRenderStats;    ///< render time statistics
-  FrameTimeStats mEventStats;     ///< event time statistics
+  // The list of stat contexts
+  StatContexts mStatContexts;
 
   Integration::PlatformAbstraction& mPlatformAbstraction; ///< platform abstraction
+  const EnvironmentOptions& mEnvironmentOptions;          ///< environment options
+  KernelTraceInterface& mKernelTrace;                     ///< kernel trace interface
 
-  typedef Dali::Vector<PerformanceMarker > MarkerVector;
-  MarkerVector mMarkers;              ///< vector of markers
-  boost::mutex mDataMutex;            ///< mutex
-  const EnvironmentOptions& mEnvironmentOptions;      ///< environment options
-  KernelTraceInterface& mKernelTrace; ///< kernel trace interface
+  unsigned int mLogLevel;         ///< log level
+  unsigned int mNextContextId;    ///< The next valid context ID
 
+  // Some defaults
+  ContextId mUpdateStats;    ///< update time statistics
+  ContextId mRenderStats;    ///< render time statistics
+  ContextId mEventStats;     ///< event time statistics
+
+  bool mLoggingEnabled:1;         ///< whether logging update / render to a log is enabled
+  bool mLogFunctionInstalled:1;   ///< whether the log function is installed
 };
 
 
index f532509..7fe9eb3 100644 (file)
@@ -94,7 +94,7 @@ void UpdateRenderSynchronization::Pause()
 {
   mPaused = true;
 
-  AddPerformanceMarker( PerformanceMarker::PAUSED );
+  AddPerformanceMarker( PerformanceInterface::PAUSED );
   mFrameTime.Suspend();
 }
 
@@ -111,7 +111,7 @@ void UpdateRenderSynchronization::Resume()
   mPausedCondition.notify_one();
   mVSyncSleepCondition.notify_one();
 
-  AddPerformanceMarker( PerformanceMarker::RESUME);
+  AddPerformanceMarker( PerformanceInterface::RESUME);
 }
 
 void UpdateRenderSynchronization::UpdateRequested()
@@ -184,13 +184,13 @@ void UpdateRenderSynchronization::UpdateReadyToRun()
     WaitSync();
   }
 
-  AddPerformanceMarker( PerformanceMarker::UPDATE_START );
+  AddPerformanceMarker( PerformanceInterface::UPDATE_START );
 }
 
 bool UpdateRenderSynchronization::UpdateSyncWithRender( bool& renderNeedsUpdate )
 {
 
-  AddPerformanceMarker( PerformanceMarker::UPDATE_END );
+  AddPerformanceMarker( PerformanceInterface::UPDATE_END );
 
   boost::unique_lock< boost::mutex > lock( mMutex );
 
@@ -285,7 +285,7 @@ bool UpdateRenderSynchronization::RenderSyncWithUpdate(RenderRequest*& requestPt
 
   if( mRunning )
   {
-    AddPerformanceMarker( PerformanceMarker::RENDER_START );
+    AddPerformanceMarker( PerformanceInterface::RENDER_START );
   }
 
   // write any new requests
@@ -321,7 +321,7 @@ void UpdateRenderSynchronization::RenderFinished( bool updateRequired, bool requ
     mRequestFinishedCondition.notify_one();
   }
 
-  AddPerformanceMarker( PerformanceMarker::RENDER_END );
+  AddPerformanceMarker( PerformanceInterface::RENDER_END );
 }
 
 void UpdateRenderSynchronization::WaitSync()
@@ -367,7 +367,7 @@ bool UpdateRenderSynchronization::VSyncNotifierSyncWithUpdateAndRender( bool val
 
   mVSyncReceivedCondition.notify_all();
 
-  AddPerformanceMarker( PerformanceMarker::V_SYNC );
+  AddPerformanceMarker( PerformanceInterface::VSYNC );
 
   while( mRunning && // sleep on condition variable WHILE still running
          !mAllowUpdateWhilePaused &&             // AND NOT allowing updates while paused
@@ -406,7 +406,7 @@ void UpdateRenderSynchronization::SetRenderRefreshRate( unsigned int numberOfVSy
   mNumberOfVSyncsPerRender = numberOfVSyncsPerRender;
 }
 
-inline void UpdateRenderSynchronization::AddPerformanceMarker( PerformanceMarker::MarkerType type )
+inline void UpdateRenderSynchronization::AddPerformanceMarker( PerformanceInterface::MarkerType type )
 {
   if( mPerformanceInterface )
   {
index 5751c78..c970e27 100644 (file)
@@ -227,7 +227,7 @@ private:
    * Helper to add a performance marker to the performance server (if its active)
    * @param type performance marker type
    */
-  void AddPerformanceMarker( PerformanceMarker::MarkerType type );
+  void AddPerformanceMarker( PerformanceInterface::MarkerType type );
 
 private:
 
index fe46a85..31f2f38 100644 (file)
@@ -739,14 +739,14 @@ void Adaptor::ProcessCoreEvents()
   {
     if( mPerformanceInterface )
     {
-      mPerformanceInterface->AddMarker( PerformanceMarker::PROCESS_EVENTS_START );
+      mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
     }
 
     mCore->ProcessEvents();
 
     if( mPerformanceInterface )
     {
-      mPerformanceInterface->AddMarker( PerformanceMarker::PROCESS_EVENTS_END );
+      mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
     }
   }
 }
index d001d82..bd2c5a9 100644 (file)
@@ -21,6 +21,7 @@ adaptor_common_internal_src_files = \
   $(adaptor_common_dir)/native-bitmap-buffer-impl.cpp \
   $(adaptor_common_dir)/object-profiler.cpp \
   $(adaptor_common_dir)/orientation-impl.cpp  \
+  $(adaptor_common_dir)/performance-logger-impl.cpp \
   $(adaptor_common_dir)/physical-keyboard-impl.cpp \
   $(adaptor_common_dir)/render-surface-impl.cpp \
   $(adaptor_common_dir)/server-connection.cpp \
diff --git a/adaptors/common/performance-logger-impl.cpp b/adaptors/common/performance-logger-impl.cpp
new file mode 100644 (file)
index 0000000..87ee690
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 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 <performance-logger-impl.h>
+#include <adaptor-impl.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+namespace
+{
+
+PerformanceInterface* GetPerformanceInterface()
+{
+  if( Adaptor::IsAvailable() )
+  {
+    return Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetPerformanceInterface();
+  }
+
+  return NULL;
+}
+
+} // Anonymous namespace
+
+PerformanceLoggerPtr PerformanceLogger::New( const char* name )
+{
+  PerformanceLoggerPtr logger = new PerformanceLogger( name );
+  return logger;
+}
+
+PerformanceLogger::PerformanceLogger( const char* name )
+: mContext( 0 )
+{
+  PerformanceInterface* performance = GetPerformanceInterface();
+  if( performance )
+  {
+    mContext = performance->AddContext( name );
+  }
+}
+
+PerformanceLogger::~PerformanceLogger()
+{
+  PerformanceInterface* performance = GetPerformanceInterface();
+  if( performance )
+  {
+    performance->RemoveContext( mContext );
+  }
+}
+
+void PerformanceLogger::AddMarker( Dali::PerformanceLogger::Marker markerType )
+{
+  PerformanceInterface* performance = GetPerformanceInterface();
+  if( performance )
+  {
+    PerformanceInterface::MarkerType newMarkerType = PerformanceInterface::START;
+    switch( markerType )
+    {
+      case Dali::PerformanceLogger::START_EVENT:
+      {
+        newMarkerType = PerformanceInterface::START;
+        break;
+      }
+      case Dali::PerformanceLogger::END_EVENT:
+      {
+        newMarkerType = PerformanceInterface::END;
+        break;
+      }
+    }
+
+    performance->AddMarker( newMarkerType, mContext );
+  }
+}
+
+void PerformanceLogger::SetLoggingFrequency( unsigned int logFrequency)
+{
+  PerformanceInterface* performance = GetPerformanceInterface();
+  if( performance )
+  {
+    performance->SetLoggingFrequency( logFrequency, mContext );
+  }
+}
+
+void PerformanceLogger::EnableLogging( bool enable )
+{
+  PerformanceInterface* performance = GetPerformanceInterface();
+  if( performance )
+  {
+    performance->EnableLogging( enable, mContext );
+  }
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
diff --git a/adaptors/common/performance-logger-impl.h b/adaptors/common/performance-logger-impl.h
new file mode 100644 (file)
index 0000000..da835a0
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef __DALI_INTERNAL_PERFORMANCE_LOGGER_H__
+#define __DALI_INTERNAL_PERFORMANCE_LOGGER_H__
+
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#include <base/interfaces/performance-interface.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.h>
+#include <performance-logger.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+class PerformanceLogger;
+
+typedef IntrusivePtr<PerformanceLogger> PerformanceLoggerPtr;
+
+/**
+ * @brief Interface for the performance logger
+ */
+class PerformanceLogger : public BaseObject
+{
+public:
+
+  /**
+   * @brief Create a new logger
+   *
+   * @param[in] name The name of the logger. This needs to be a compile-time literal and alive for the whole lifetime of the performance logger.
+   * @return a new logger
+   */
+  static PerformanceLoggerPtr New( const char* name );
+
+  /**
+   * Constructor
+   * @param[in] name The name to assing to the logger
+   */
+  PerformanceLogger( const char* name );
+
+  /**
+   * Destructor.
+   */
+  virtual ~PerformanceLogger();
+
+  /**
+   * Add a performance marker
+   *
+   * @param markerType Performance marker type
+   */
+  void AddMarker( Dali::PerformanceLogger::Marker markerType );
+
+  /**
+   * Set the logging frequency
+   *
+   * @param logFrequency how often to log out in seconds
+   */
+  void SetLoggingFrequency( unsigned int logFrequency);
+
+  /**
+   * Set logging on or off for this logger
+   *
+   * @param[in] enable Enable logging or not
+   */
+  void EnableLogging( bool enable );
+
+private: // Implementation
+
+  // not implemented
+  PerformanceLogger( const PerformanceLogger& );
+  PerformanceLogger& operator=( const PerformanceLogger& );
+
+private:
+
+  PerformanceInterface::ContextId mContext;   ///< Context of this logger
+
+};
+
+// Helpers for public-api forwarding methods
+
+inline static Internal::Adaptor::PerformanceLogger& GetImplementation( Dali::PerformanceLogger& logger )
+{
+  DALI_ASSERT_ALWAYS( logger && "PerformanceLogger handle is empty" );
+
+  BaseObject& handle = logger.GetBaseObject();
+
+  return static_cast< Internal::Adaptor::PerformanceLogger& >( handle );
+}
+
+inline static const  Internal::Adaptor::PerformanceLogger& GetImplementation( const Dali::PerformanceLogger& logger )
+{
+  DALI_ASSERT_ALWAYS( logger && "PerformanceLogger handle is empty" );
+
+  const BaseObject& handle = logger.GetBaseObject();
+
+  return static_cast< const Internal::Adaptor::PerformanceLogger& >( handle );
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_PERFORMANCE_LOGGER_H__
diff --git a/adaptors/public-api/adaptor-framework/performance-logger.cpp b/adaptors/public-api/adaptor-framework/performance-logger.cpp
new file mode 100644 (file)
index 0000000..ffff65a
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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 <performance-logger.h>
+
+// INTERNAL INCLUDES
+#include <performance-logger-impl.h>
+
+namespace Dali
+{
+
+PerformanceLogger::PerformanceLogger()
+{
+}
+
+PerformanceLogger PerformanceLogger::New( const char* name )
+{
+  Internal::Adaptor::PerformanceLoggerPtr internal = Internal::Adaptor::PerformanceLogger::New( name );
+  return PerformanceLogger(internal.Get());
+}
+
+PerformanceLogger::PerformanceLogger( const PerformanceLogger& performanceLogger )
+: BaseHandle(performanceLogger)
+{
+}
+
+PerformanceLogger& PerformanceLogger::operator=( const PerformanceLogger& performanceLogger )
+{
+  // check self assignment
+  if( *this != performanceLogger )
+  {
+    BaseHandle::operator=(performanceLogger);
+  }
+  return *this;
+}
+
+PerformanceLogger::~PerformanceLogger()
+{
+}
+
+PerformanceLogger PerformanceLogger::DownCast( BaseHandle handle )
+{
+  return PerformanceLogger( dynamic_cast<Internal::Adaptor::PerformanceLogger*>( handle.GetObjectPtr() ) );
+}
+
+void PerformanceLogger::AddMarker( Marker markerType )
+{
+  Internal::Adaptor::GetImplementation(*this).AddMarker( markerType );
+}
+
+void PerformanceLogger::SetLoggingFrequency( unsigned int logFrequency)
+{
+  Internal::Adaptor::GetImplementation(*this).SetLoggingFrequency( logFrequency );
+}
+
+void PerformanceLogger::EnableLogging( bool enable )
+{
+  Internal::Adaptor::GetImplementation(*this).EnableLogging( enable );
+}
+
+PerformanceLogger::PerformanceLogger(Internal::Adaptor::PerformanceLogger* PerformanceLogger)
+: BaseHandle(PerformanceLogger)
+{
+}
+
+} // namespace Dali
diff --git a/adaptors/public-api/adaptor-framework/performance-logger.h b/adaptors/public-api/adaptor-framework/performance-logger.h
new file mode 100644 (file)
index 0000000..b543a02
--- /dev/null
@@ -0,0 +1,133 @@
+#ifndef __DALI_PERFORMANCE_LOGGER_H__
+#define __DALI_PERFORMANCE_LOGGER_H__
+
+/*
+ * Copyright (c) 2014 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 <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+
+namespace Internal DALI_INTERNAL
+{
+namespace Adaptor
+{
+class PerformanceLogger;
+}
+}
+
+/**
+ * @brief Performance logger class
+ */
+class DALI_IMPORT_API PerformanceLogger : public BaseHandle
+{
+public:
+
+  /**
+   * Enum for events that can be logged
+   */
+  enum Marker
+  {
+    START_EVENT,      ///< The start of timing
+    END_EVENT         ///< The end of timing
+  };
+
+  /**
+   * @brief Constructor, creates an uninitialized logger.
+   *
+   * Call New to fully construct a logger.
+   */
+  PerformanceLogger();
+
+  /**
+   * @brief Create a new logger
+   *
+   * @param[in] name The name of the logger. This needs to be a compile-time literal and alive for the whole lifetime of the performance logger.
+   * @return a new logger
+   */
+  static PerformanceLogger New( const char* name );
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] logger The handle to copy. The copied handle will point at the same implementation
+   */
+  PerformanceLogger( const PerformanceLogger& logger );
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] logger The handle to copy. This handle will point at the same implementation
+   * as the copied handle.
+   * @return Reference to this logger handle
+   */
+  PerformanceLogger& operator=( const PerformanceLogger& logger );
+
+  /**
+   * @brief Destructor
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   */
+  ~PerformanceLogger();
+
+  /**
+   * @brief Downcast an Object handle to PerformanceLogger handle.
+   *
+   * If handle points to a PerformanceLogger object the downcast produces a valid
+   * handle. If not the returned handle is left uninitialized.
+   *
+   * @param[in] handle to An object
+   * @return handle to a PerformanceLogger object or an uninitialized handle
+   */
+  static PerformanceLogger DownCast( BaseHandle handle );
+
+  /**
+   * Add a performance marker
+   *
+   * @param markerType Performance marker type
+   */
+  void AddMarker( Marker markerType );
+
+  /**
+   * Set the logging frequency
+   *
+   * @param logFrequency how often to log out in seconds
+   */
+  void SetLoggingFrequency( unsigned int logFrequency);
+
+  /**
+   * Set logging on or off for this logger
+   *
+   * @param[in] enable Enable logging or not
+   */
+  void EnableLogging( bool enable );
+
+  // Not intended for application developers
+
+  /**
+   * Creates a new handle from the implementation.
+   * @param[in] impl A pointer to the object.
+   */
+  explicit DALI_INTERNAL PerformanceLogger( Internal::Adaptor::PerformanceLogger* impl );
+
+};
+
+} // namespace Dali
+
+#endif // __DALI_PERFORMANCE_LOGGER_H__
index 47ad33a..4ff97d1 100644 (file)
@@ -42,6 +42,7 @@
 #include <dali/public-api/adaptor-framework/lifecycle-controller.h>
 #include <dali/public-api/adaptor-framework/orientation.h>
 #include <dali/public-api/adaptor-framework/physical-keyboard.h>
+#include <dali/public-api/adaptor-framework/performance-logger.h>
 #include <dali/public-api/adaptor-framework/pixmap-image.h>
 #include <dali/public-api/adaptor-framework/render-surface.h>
 #include <dali/public-api/adaptor-framework/singleton-service.h>
index 2d05a5a..f0b1785 100644 (file)
@@ -15,6 +15,7 @@ public_api_src_files = \
   $(adaptor_public_api_dir)/adaptor-framework/lifecycle-controller.cpp \
   $(adaptor_public_api_dir)/adaptor-framework/orientation.cpp \
   $(adaptor_public_api_dir)/adaptor-framework/physical-keyboard.cpp \
+  $(adaptor_public_api_dir)/adaptor-framework/performance-logger.cpp \
   $(adaptor_public_api_dir)/adaptor-framework/pixmap-image.cpp \
   $(adaptor_public_api_dir)/adaptor-framework/render-surface.cpp \
   $(adaptor_public_api_dir)/adaptor-framework/singleton-service.cpp \
@@ -51,6 +52,7 @@ public_api_adaptor_framework_header_files = \
   $(adaptor_public_api_dir)/adaptor-framework/lifecycle-controller.h \
   $(adaptor_public_api_dir)/adaptor-framework/orientation.h \
   $(adaptor_public_api_dir)/adaptor-framework/physical-keyboard.h \
+  $(adaptor_public_api_dir)/adaptor-framework/performance-logger.h \
   $(adaptor_public_api_dir)/adaptor-framework/pixmap-image.h \
   $(adaptor_public_api_dir)/adaptor-framework/render-surface.h \
   $(adaptor_public_api_dir)/adaptor-framework/singleton-service.h \