Improved performance logging 88/34688/13
authorNick Holland <nick.holland@partner.samsung.com>
Fri, 30 Jan 2015 11:55:29 +0000 (11:55 +0000)
committerNick Holland <nick.holland@partner.samsung.com>
Thu, 5 Feb 2015 13:31:55 +0000 (05:31 -0800)
Seperated performance logging into 2 environment variables.
Plus added a new one for controlling the frequency of logging statistics

Before one environment variable would do multiple un-related things.

--DALI_LOG_PERFORMANCE_STATS--

A bitmask to control which DALi performance statstics are logged out.

The bitmask provided is
  LOG_EVERYTHING        ///< Bit 0 (1), log all statistics to the DALi log
  LOG_UPDATE_RENDER     ///< Bit 1 (2), log update and render statistics to the DALi log
  LOG_EVENT_PROCESS     ///< Bit 2 (4), log event task statistics to the DALi log
  LOG_CUSTOM_MARKERS    ///< Bit 3 (8), log custom marker statistics to the DALi log

Example output of running:  DALI_LOG_PERFORMANCE_STATS=1 dali-demo
with a custom PerformanceLogger for dali-demo TableView Initialize()

INFO: DALI: Update, min 0.20 ms, max 2.47 ms, total (0.1 secs), avg 0.54 ms, std dev 0.25 ms
INFO: DALI: Render, min 0.06 ms, max 19.10 ms, total (0.1 secs), avg 0.94 ms, std dev 1.86 ms
INFO: DALI: Event, min 0.01 ms, max 9.38 ms, total (0.0 secs), avg 0.66 ms, std dev 2.02 ms
INFO: DALI: DaliTableView, min 81.11 ms, max 81.11 ms, total (0.1 secs), avg 81.11 ms, std dev 0.00 ms

--DALI_LOG_PERFORMANCE_STATS_FREQ--
Used to control the frequency of DALI_LOG_PERFORMANCE_STATS, e.g.
to log the statistics out every 5 seconds:

DALI_LOG_PERFORMANCE_STATS_FREQ=5 DALI_LOG_PERFORMANCE_STATS=1 dali-demo

--DALI_PERFORMANCE_TIMESTAMP_OUTPUT--

A bitmask to enable logging of time stamped events.

  OUTPUT_DALI_LOG            ///< Bit 1 (1), log markers to DALi log
  OUTPUT_KERNEL_TRACE        ///< Bit 2 (2), log makers to kernel trace
  OUTPUT_SYSTEM_TRACE        ///< Bit 3 (4), log markers to system trace ( currently not supported)

Example output of: DALI_PERFORMANCE_TIMESTAMP_OUTPUT=1 dali-demo

INFO: DALI: 966735.553251 (seconds), V_SYNC
INFO: DALI: 966735.553279 (seconds), UPDATE_START
INFO: DALI: 966735.553872 (seconds), UPDATE_END
INFO: DALI: 966735.553890 (seconds), RENDER_START
INFO: DALI: 966735.553933 (seconds), PROCESS_EVENT_START
INFO: DALI: 966735.554011 (seconds), PROCESS_EVENT_END
INFO: DALI: 966735.567137 (seconds), RENDER_END
INFO: DALI: 966735.570027 (seconds), V_SYNC

Change-Id: I392e9d3312111ce2d037e91b821996f43b4b842c

16 files changed:
adaptors/base/environment-options.cpp
adaptors/base/environment-options.h
adaptors/base/environment-variables.h
adaptors/base/file.list
adaptors/base/interfaces/performance-interface.h
adaptors/base/performance-logging/frame-time-stamp.cpp
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/performance-logging/statistics/stat-context-log-interface.h [new file with mode: 0644]
adaptors/base/performance-logging/statistics/stat-context-manager.cpp [new file with mode: 0644]
adaptors/base/performance-logging/statistics/stat-context-manager.h [new file with mode: 0644]
adaptors/base/performance-logging/statistics/stat-context.cpp [new file with mode: 0644]
adaptors/base/performance-logging/statistics/stat-context.h [new file with mode: 0644]
adaptors/common/adaptor-impl.cpp

index 4dc7e78..8f2cb00 100644 (file)
@@ -27,10 +27,16 @@ namespace Internal
 namespace Adaptor
 {
 
+namespace
+{
+const unsigned int DEFAULT_STATISTICS_LOG_FREQUENCY = 2;
+}
 EnvironmentOptions::EnvironmentOptions()
 : mFpsFrequency(0),
   mUpdateStatusFrequency(0),
-  mPerformanceLoggingLevel(0),
+  mPerformanceStatsLevel(0),
+  mPerformanceStatsFrequency( DEFAULT_STATISTICS_LOG_FREQUENCY),
+  mPerformanceTimeStampOutput(0),
   mPanGestureLoggingLevel(0),
   mPanGesturePredictionMode(-1),
   mPanGesturePredictionAmount(-1), ///< only sets value in pan gesture if greater than 0
@@ -53,13 +59,17 @@ EnvironmentOptions::~EnvironmentOptions()
 void EnvironmentOptions::SetLogOptions( const Dali::Integration::Log::LogFunction& logFunction,
                              unsigned int logFrameRateFrequency,
                              unsigned int logupdateStatusFrequency,
-                             unsigned int logPerformanceLevel,
+                             unsigned int logPerformanceStats,
+                             unsigned int logPerformanceStatsFrequency,
+                             unsigned int performanceTimeStampOutput,
                              unsigned int logPanGestureLevel )
 {
   mLogFunction = logFunction;
   mFpsFrequency = logFrameRateFrequency;
   mUpdateStatusFrequency = logupdateStatusFrequency;
-  mPerformanceLoggingLevel = logPerformanceLevel;
+  mPerformanceStatsLevel = logPerformanceStats;
+  mPerformanceStatsFrequency = logPerformanceStatsFrequency;
+  mPerformanceTimeStampOutput= performanceTimeStampOutput;
   mPanGestureLoggingLevel = logPanGestureLevel;
 }
 
@@ -83,9 +93,17 @@ unsigned int EnvironmentOptions::GetUpdateStatusLoggingFrequency() const
   return mUpdateStatusFrequency;
 }
 
-unsigned int EnvironmentOptions::GetPerformanceLoggingLevel() const
+unsigned int EnvironmentOptions::GetPerformanceStatsLoggingOptions() const
 {
-  return mPerformanceLoggingLevel;
+  return mPerformanceStatsLevel;
+}
+unsigned int EnvironmentOptions::GetPerformanceStatsLoggingFrequency() const
+{
+  return mPerformanceStatsFrequency;
+}
+unsigned int EnvironmentOptions::GetPerformanceTimeStampOutput() const
+{
+  return mPerformanceTimeStampOutput;
 }
 
 unsigned int EnvironmentOptions::GetPanGestureLoggingLevel() const
@@ -188,11 +206,17 @@ void EnvironmentOptions::SetGlesCallTime( int time )
   mGlesCallTime = time;
 }
 
-int EnvironmentOptions::GetGlesCallTime()
+int EnvironmentOptions::GetGlesCallTime() const
 {
   return mGlesCallTime;
 }
 
+bool EnvironmentOptions::PerformanceServerRequired() const
+{
+  return ( (GetPerformanceStatsLoggingOptions() > 0) ||
+           ( GetPerformanceTimeStampOutput() > 0 ) );
+}
+
 } // Adaptor
 
 } // Internal
index 5d107d3..fe74fc9 100644 (file)
@@ -50,13 +50,17 @@ public:
    * @param logFilterOptions bitmask of the logging options defined in intergration/debug.h (e.g.
    * @param logFrameRateFrequency frequency of how often FPS is logged out (e.g. 0 = off, 2 = every 2 seconds).
    * @param logupdateStatusFrequency frequency of how often the update status is logged in number of frames
-   * @param logPerformanceLevel performance logging, 0 = disabled,  1+ =  enabled
+   * @param logPerformanceStats performance statistics logging, 0 = disabled,  1+ =  enabled
+   * @param logPerformanceStatsFrequency statistics logging frequency in seconds
+   * @param performanceTimeStampOutput where to output performance related time stamps to
    * @param logPanGestureLevel pan-gesture logging, 0 = disabled,  1 = enabled
    */
   void SetLogOptions( const Dali::Integration::Log::LogFunction& logFunction,
                        unsigned int logFrameRateFrequency,
                        unsigned int logupdateStatusFrequency,
-                       unsigned int logPerformanceLevel,
+                       unsigned int logPerformanceStats,
+                       unsigned int logPerformanceStatsFrequency,
+                       unsigned int performanceTimeStampOutput,
                        unsigned int logPanGestureLevel );
 
   /**
@@ -80,9 +84,19 @@ public:
   unsigned int GetUpdateStatusLoggingFrequency() const;
 
   /**
-   * @return logPerformanceLevel performance log level ( 0 = off )
+   * @return performance statistics log level ( 0 == off )
    */
-  unsigned int GetPerformanceLoggingLevel() const;
+  unsigned int GetPerformanceStatsLoggingOptions() const;
+
+  /**
+   * @return performance statistics log frequency in seconds
+   */
+  unsigned int GetPerformanceStatsLoggingFrequency() const;
+
+  /**
+   * @return performance time stamp output ( 0 == off)
+   */
+  unsigned int GetPerformanceTimeStampOutput() const;
 
   /**
    * @return pan-gesture logging level ( 0 == off )
@@ -211,14 +225,20 @@ public:
   /**
    * @brief Get the graphics status time
    */
-  int GetGlesCallTime();
+  int GetGlesCallTime() const;
 
+  /**
+   * @return true if performance server is required
+   */
+  bool PerformanceServerRequired() const;
 
 private:
 
   unsigned int mFpsFrequency;                     ///< how often fps is logged out in seconds
   unsigned int mUpdateStatusFrequency;            ///< how often update status is logged out in frames
-  unsigned int mPerformanceLoggingLevel;          ///< performance log level
+  unsigned int mPerformanceStatsLevel;            ///< performance statistics logging bitmask
+  unsigned int mPerformanceStatsFrequency;        ///< performance statistics logging frequency (seconds)
+  unsigned int mPerformanceTimeStampOutput;       ///< performance time stamp output ( bitmask)
   unsigned int mPanGestureLoggingLevel;           ///< pan-gesture log level
   int mPanGesturePredictionMode;                  ///< prediction mode for pan gestures
   int mPanGesturePredictionAmount;                ///< prediction amount for pan gestures
index de7760f..006b058 100644 (file)
@@ -27,7 +27,23 @@ namespace Internal
 namespace Adaptor
 {
 
-#define DALI_ENV_LOG_PERFORMANCE "DALI_LOG_PERFORMANCE"
+/**
+ * What performance statistics are logged out to dlog
+ * see StatisticsLogOptions in performance-interface.h for values
+ */
+#define DALI_ENV_LOG_PERFORMANCE_STATS "DALI_LOG_PERFORMANCE_STATS"
+
+/**
+ * How frequent in seconds to log out performance statistics
+ */
+#define DALI_ENV_LOG_PERFORMANCE_STATS_FREQUENCY "DALI_LOG_PERFORMANCE_STATS_FREQ"
+
+/**
+ * Where timestamped events for update/render/event and custom events
+ * are output.
+ * see TimeStampOutput in performance-interface.h for values
+ */
+#define DALI_ENV_PERFORMANCE_TIMESTAMP_OUTPUT "DALI_PERFORMANCE_TIMESTAMP_OUTPUT"
 
 // environment variable for enabling/disabling fps tracking
 #define DALI_ENV_FPS_TRACKING "DALI_FPS_TRACKING"
index 9e38a94..4336b56 100644 (file)
@@ -11,5 +11,7 @@ base_adaptor_src_files = \
   $(base_adaptor_src_dir)/environment-options.cpp \
   $(base_adaptor_src_dir)/performance-logging/frame-time-stats.cpp \
   $(base_adaptor_src_dir)/performance-logging/performance-marker.cpp \
+  $(base_adaptor_src_dir)/performance-logging/statistics/stat-context.cpp \
+  $(base_adaptor_src_dir)/performance-logging/statistics/stat-context-manager.cpp \
   $(base_adaptor_src_dir)/performance-logging/performance-server.cpp \
   $(base_adaptor_src_dir)/performance-logging/performance-interface-factory.cpp
index 25e71fe..3f41f97 100644 (file)
@@ -39,21 +39,49 @@ public:
   typedef unsigned short ContextId;   ///< Type to represent a context ID
 
   /**
-   * bitmask of logging options
+   * bitmask of statistics logging options.
+   * Used for output data like min/max/average time spent in event, update,render and custom tasks.
+   * E.g.
+   * Event, min 0.04 ms, max 5.27 ms, total (0.1 secs), avg 0.28 ms, std dev 0.73 ms
+   * Update, min 0.29 ms, max 0.91 ms, total (0.5 secs), avg 0.68 ms, std dev 0.15 ms
+   * Render, min 0.33 ms, max 0.97 ms, total (0.6 secs), avg 0.73 ms, std dev 0.17 ms
+   * TableViewInit, min 76.55 ms, max 76.55 ms, total (0.1 secs), avg 76.55 ms, std dev 0.00 ms
    */
-  enum LogLevel
+  enum StatisticsLogOptions
   {
     DISABLED             = 0,
-    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
+    LOG_EVERYTHING       = 1 << 0, ///< Bit 0 (1), log all statistics to the DALi log
+    LOG_UPDATE_RENDER    = 1 << 1, ///< Bit 1 (2), log update and render statistics to the DALi log
+    LOG_EVENT_PROCESS    = 1 << 2, ///< Bit 2 (4), log event task statistics to the DALi log
+    LOG_CUSTOM_MARKERS   = 1 << 3, ///< Bit 3 (8), log custom marker statistics to the DALi log
+  };
+
+  /**
+   * bitmask of time stamp output options
+   * Used for logging out time stamped markers for detailed analysis (see MarkerType, for the markers logged)
+   * Typical output would look like:
+   *   379.059025 (seconds), V_SYNC
+   *   379.059066 (seconds), UPDATE_START
+   *   379.059747 (seconds), UPDATE_END
+   *   379.059820 (seconds), RENDER_START
+   *   379.060708 (seconds), RENDER_END
+   *   379.075795 (seconds), V_SYNC
+   *   379.076444 (seconds), MY_CUSTOM_MARKER_START  ( customer marker using PerformanceLogger public API).
+   *   379.077353 (seconds), MY_CUSTOM_MARKER_END  ( customer marker using PerformanceLogger public API).
+   */
+  enum TimeStampOutput
+  {
+    NO_TIME_STAMP_OUTPUT         = 0,
+    OUTPUT_DALI_LOG              = 1 << 0, ///< Bit 1 (1), log markers to DALi log
+    OUTPUT_KERNEL_TRACE          = 1 << 1, ///< Bit 2 (2), log makers to kernel trace
+    OUTPUT_SYSTEM_TRACE          = 1 << 2, ///< Bit 3 (4), log markers to system trace
+    OUTPUT_NETWORK               = 1 << 3, ///< Bit 4 (8), log markers to network client
   };
 
   /**
    * enum for difference performance markers.
    * Please modify the name lookup table in performance-interface.cpp
-   * file if adding new markers.
+   * file if adding new markers (the order must match one to one).
    */
   enum MarkerType
   {
@@ -83,7 +111,7 @@ public:
   virtual ~PerformanceInterface() {};
 
   /**
-   * Add a new context with a given name
+   * @brief Add a new context with a given name
    *
    * @param[in] name The name of the context
    * @return Return the unique id for this context
@@ -91,44 +119,45 @@ public:
   virtual ContextId AddContext( const char* name ) = 0;
 
   /**
-   * Remove a context from use
+   * @brief 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
+   * @brief 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
+   * @param[in] markerType performance marker type
    */
   virtual void AddMarker( MarkerType markerType ) = 0;
 
   /**
-   * Add a performance marker
+   * @brief Add a performance marker for a used defined context
    * 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.
+   * @param[in] markerType performance marker type
+   * @param[in] 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
-   * @param level 0 = disabled, 1 = enabled
-   * @param logFrequency how often to log out in seconds
+   * @brief Set the logging level and frequency
+   * @param[in] StatisticsLogOptions  0 = disabled, >0 bitmask of StatisticsLogOptions
+   * @param[in] timeStampOutput 0 = disabled, > 0 bitmask of TimeStampOutput options.
+   * @param[in] logFrequency how often to log out in seconds
    */
-  virtual void SetLogging( unsigned int level, unsigned int logFrequency) = 0;
+  virtual void SetLogging( unsigned int statisticsLogOptions, unsigned int timeStampOutput, unsigned int logFrequency) = 0;
 
   /**
-   * Set the logging frequency
+   * @brief Set the logging frequency for an individual context
    *
-   * @param logFrequency how often to log out in seconds
+   * @param[in] 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
+   * @brief 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.
index d59adb0..4fe539d 100644 (file)
@@ -61,7 +61,7 @@ FrameTimeStamp::FrameTimeStamp(unsigned int bufferIndex )
 
 unsigned int FrameTimeStamp::MicrosecondDiff( const FrameTimeStamp& start,const FrameTimeStamp& end )
 {
-  unsigned int microDiff = end.microseconds - start.microseconds;
+  int microDiff = end.microseconds - start.microseconds;
   unsigned int secDiff = ( end.seconds - start.seconds ) * MICROSECONDS_PER_SECOND;
   return ( microDiff + secDiff);
 }
index 4e08d17..15e9b52 100644 (file)
 // CLASS HEADER
 #include "performance-marker.h"
 
+// INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+
+
 namespace Dali
 {
 
@@ -27,6 +32,37 @@ namespace Internal
 namespace Adaptor
 {
 
+namespace
+{
+
+struct NamePair
+{
+  PerformanceInterface::MarkerType type;
+  const char* const name;
+  PerformanceMarker::MarkerFilter group;
+  PerformanceMarker::MarkerEventType eventType;
+};
+
+const NamePair MARKER_LOOKUP[] =
+{
+    { PerformanceInterface::VSYNC       ,         "V_SYNC"               , PerformanceMarker::V_SYNC_EVENTS, PerformanceMarker::SINGLE_EVENT      },
+    { PerformanceInterface::UPDATE_START ,        "UPDATE_START"         , PerformanceMarker::UPDATE,        PerformanceMarker::START_TIMED_EVENT },
+    { PerformanceInterface::UPDATE_END   ,        "UPDATE_END"           , PerformanceMarker::UPDATE,        PerformanceMarker::END_TIMED_EVENT   },
+    { PerformanceInterface::RENDER_START ,        "RENDER_START"         , PerformanceMarker::RENDER,        PerformanceMarker::START_TIMED_EVENT },
+    { PerformanceInterface::RENDER_END   ,        "RENDER_END"           , PerformanceMarker::RENDER,        PerformanceMarker::END_TIMED_EVENT   },
+    { PerformanceInterface::SWAP_START   ,        "SWAP_START"           , PerformanceMarker::SWAP_BUFFERS,  PerformanceMarker::START_TIMED_EVENT },
+    { PerformanceInterface::SWAP_END     ,        "SWAP_END"             , PerformanceMarker::SWAP_BUFFERS,  PerformanceMarker::END_TIMED_EVENT   },
+    { PerformanceInterface::PROCESS_EVENTS_START, "PROCESS_EVENT_START"  , PerformanceMarker::EVENT_PROCESS, PerformanceMarker::START_TIMED_EVENT },
+    { PerformanceInterface::PROCESS_EVENTS_END,   "PROCESS_EVENT_END"    , PerformanceMarker::EVENT_PROCESS, PerformanceMarker::END_TIMED_EVENT   },
+    { PerformanceInterface::PAUSED       ,        "PAUSED"               , PerformanceMarker::LIFE_CYCLE_EVENTS, PerformanceMarker::SINGLE_EVENT  },
+    { PerformanceInterface::RESUME       ,        "RESUMED"              , PerformanceMarker::LIFE_CYCLE_EVENTS, PerformanceMarker::SINGLE_EVENT  },
+    { PerformanceInterface::START        ,        "START"                , PerformanceMarker::CUSTOM_EVENTS, PerformanceMarker::START_TIMED_EVENT  },
+    { PerformanceInterface::END          ,        "END"                  , PerformanceMarker::CUSTOM_EVENTS, PerformanceMarker::END_TIMED_EVENT  }
+};
+} // un-named namespace
+
+
+
 PerformanceMarker::PerformanceMarker( PerformanceInterface::MarkerType type )
 :mType(type)
 {
@@ -38,11 +74,27 @@ PerformanceMarker::PerformanceMarker( PerformanceInterface::MarkerType type, Fra
 {
 }
 
+const char* const PerformanceMarker::GetName( ) const
+{
+  return MARKER_LOOKUP[ mType ].name;
+}
+
+PerformanceMarker::MarkerEventType PerformanceMarker::GetEventType() const
+{
+  return MARKER_LOOKUP[ mType ].eventType;
+}
+
 unsigned int PerformanceMarker::MicrosecondDiff( const PerformanceMarker& start,const PerformanceMarker& end )
 {
   return FrameTimeStamp::MicrosecondDiff( start.mTimeStamp, end.mTimeStamp );
 }
 
+bool PerformanceMarker::IsFilterEnabled( MarkerFilter filter ) const
+{
+  return  (filter & MARKER_LOOKUP[ mType ].group);
+}
+
+
 } // namespace Adaptor
 
 } // namespace Internal
index 593a401..b6ac794 100644 (file)
@@ -38,16 +38,46 @@ class PerformanceMarker
 {
 public:
 
+
+  /**
+   * Bitmask used to filter different types of markers based
+   * on what group they belong to.
+   */
+  enum MarkerFilter
+  {
+    FILTERING_DISABLED   = 0,      ///< disabled
+    V_SYNC_EVENTS        = 1 << 0, ///< v-sync
+    UPDATE               = 1 << 1, ///< update start / end
+    RENDER               = 1 << 2, ///< render start / end
+    EVENT_PROCESS        = 1 << 3, ///< process events start / end
+    SWAP_BUFFERS         = 1 << 4, ///< swap buffers start / end
+    LIFE_CYCLE_EVENTS    = 1 << 5, ///< pause / resume
+    RESOURCE_EVENTS      = 1 << 6, ///< resource events
+    CUSTOM_EVENTS        = 1 << 7
+  };
+
   /**
-   * Constructor
-   * @param type marker type
+   * Marker event type
+   */
+  enum MarkerEventType
+  {
+    SINGLE_EVENT,           ///< event is something that has no duration associated with it
+    START_TIMED_EVENT,      ///< start of a timed event
+    END_TIMED_EVENT         ///< end of a timed event
+
+  };
+
+
+  /**
+   * @brief Constructor
+   * @param[in] type marker type
    */
   PerformanceMarker( PerformanceInterface::MarkerType type );
 
   /**
-   * Constructor
-   * @param type marker type
-   * @param time time stamp
+   * @brief Constructor
+   * @param[in] type marker type
+   * @param[in] time time stamp
    */
   PerformanceMarker( PerformanceInterface::MarkerType type,  FrameTimeStamp time );
 
@@ -68,12 +98,26 @@ public:
   }
 
   /**
+   * @return the event type of marker
+   */
+  MarkerEventType GetEventType() const;
+
+  /**
+   * @return marker name
+   */
+  const char* const GetName( ) const;
+
+  /**
    * @param start the start marker
    * @param end the end marker
    * @return difference in microseconds between two markers
    */
   static unsigned int MicrosecondDiff( const PerformanceMarker& start, const PerformanceMarker& end  );
 
+  /**
+   * @return if a marker is enabled as part of a group
+   */
+  bool IsFilterEnabled( MarkerFilter filter ) const;
 private:
 
   PerformanceInterface::MarkerType mType;         ///< marker type
index 5187387..2736ad2 100644 (file)
@@ -31,40 +31,19 @@ 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 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)
 :mPlatformAbstraction( adaptorServices.GetPlatformAbstractionInterface() ),
  mEnvironmentOptions( environmentOptions ),
  mKernelTrace( adaptorServices.GetKernelTraceInterface() ),
- mLogLevel( 0 ),
- mNextContextId( 0 ),
+ mStatContextManager( *this ),
+ mStatisticsLogBitmask( 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());
+  SetLogging( mEnvironmentOptions.GetPerformanceStatsLoggingOptions(),
+              mEnvironmentOptions.GetPerformanceTimeStampOutput(),
+              mEnvironmentOptions.GetPerformanceStatsLoggingFrequency());
 }
 
 PerformanceServer::~PerformanceServer()
@@ -73,332 +52,148 @@ 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 logFrequency)
+void PerformanceServer::SetLogging( unsigned int statisticsLogOptions,
+                                    unsigned int timeStampOutput,
+                                    unsigned int logFrequency )
 {
-  if( level == 0 )
+  if( ( statisticsLogOptions == 0) && ( timeStampOutput == 0 ))
   {
     mLoggingEnabled = false;
     return;
   }
-  mLogLevel = level;
 
-  EnableLogging( mLogLevel & LOG_UPDATE_RENDER, mUpdateStats );
-  EnableLogging( mLogLevel & LOG_UPDATE_RENDER, mRenderStats );
-  EnableLogging( mLogLevel & LOG_EVENT_PROCESS, mEventStats );
+  mStatisticsLogBitmask = statisticsLogOptions;
+  mPerformanceOutputBitmask = timeStampOutput;
 
-  SetLoggingFrequency( logFrequency, mUpdateStats );
-  SetLoggingFrequency( logFrequency, mRenderStats );
-  SetLoggingFrequency( logFrequency, mEventStats );
+  mStatContextManager.SetLoggingLevel( mStatisticsLogBitmask, logFrequency);
 
   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 );
-  }
+  mStatContextManager.SetLoggingFrequency( logFrequency, contextId );
 }
 
 void PerformanceServer::EnableLogging( bool enable, ContextId contextId )
 {
-  StatContext* context = GetContext( contextId );
-  if( context )
-  {
-    context->EnableLogging( enable );
-  }
-}
-
-PerformanceServer::StatContext::StatContext()
-: mName( NULL ),
-  mId( 0 ),
-  mLogFrequencyMicroseconds( DEFAULT_LOG_FREQUENCEY * MICROSECONDS_PER_SECOND ),
-  mLog( true )
-{
-}
-
-PerformanceServer::StatContext::StatContext( unsigned int id, const char* contextName )
-: mName( contextName ),
-  mId( id ),
-  mLogFrequencyMicroseconds( DEFAULT_LOG_FREQUENCEY * MICROSECONDS_PER_SECOND ),
-  mLog( true )
-{
+  mStatContextManager.EnableLogging( enable, contextId );
 }
 
 PerformanceInterface::ContextId PerformanceServer::AddContext( const char* name )
 {
-  unsigned int contextId = mNextContextId++;
-
-  DALI_ASSERT_DEBUG( !GetContext( contextId ) );
-
-  mStatContexts.PushBack( new StatContext( contextId, name ) );
-
-  return contextId;
+  // for adding custom contexts
+  return mStatContextManager.AddContext( name, PerformanceMarker::CUSTOM_EVENTS );
 }
 
 void PerformanceServer::RemoveContext( ContextId contextId )
 {
-  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
-  {
-    StatContext* context = *it;
-
-    if( context->GetId() == contextId )
-    {
-      delete context;
-
-      mStatContexts.Erase( it );
-      break;
-    }
-  }
-}
-
-PerformanceServer::StatContext* PerformanceServer::GetContext( ContextId contextId )
-{
-  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
-  {
-    StatContext* context = *it;
-
-    if( context->GetId() == contextId )
-    {
-      return context;
-    }
-  }
-
-  return NULL;
-}
-
-void PerformanceServer::AddMarker( MarkerType markerType )
-{
-  switch( markerType )
-  {
-    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;
-    }
-  }
+  mStatContextManager.RemoveContext( contextId );
 }
 
 void PerformanceServer::AddMarker( MarkerType markerType, ContextId contextId )
 {
+  // called only for custom markers
+
   if( !mLoggingEnabled )
   {
     return;
   }
 
-  // Get the time
+  // This is only called from main event thread, but may overlap with internal AddMarker calls
+  // from other threads ( update, render etc).
+  boost::mutex::scoped_lock sharedDatalock( mDataMutex );
+
+  // Get the time stamp
   unsigned int seconds = 0;
   unsigned int microseconds = 0;
   mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
 
-  // Create a marker and add it to the log
+  // Create a marker
   PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ) );
-  AddMarkerToLog( marker, contextId );
-}
 
-void PerformanceServer::AddMarkerToLog( const PerformanceMarker& marker, ContextId contextId )
-{
-  StatContext* context = GetContext( contextId );
-  if( context )
-  {
-    if( mLogLevel & LOG_EVENTS_TO_KERNEL )
-    {
-      std::stringstream ss;
-      ss << GetMarkerName( marker.GetType() ) << ":" << ( ( context->GetName() ) ? context->GetName() : "" );
-      mKernelTrace.Trace( ss.str() );
-    }
+  // get the marker description for this context, e.g SIZE_NEGOTIATION_START
+  const char* const description = mStatContextManager.GetMarkerDescription( markerType, contextId );
 
-    // 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;
-      }
-    }
+  // log it
+  LogMarker( marker, description );
 
-    context->LogMarker( marker );
-  }
-}
+  // Add custom marker to statistics context manager
+  mStatContextManager.AddCustomMarker( marker, contextId );
 
-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 ", 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::StatContext::TimeMarkers()
+void PerformanceServer::AddMarker( MarkerType markerType )
 {
-  // insert time stamps into a frame-time-stats object, based on type
-  for( MarkerVector::SizeType i = 0; i < mMarkers.Size(); ++i)
+  // called only for internal markers
+
+  if( !mLoggingEnabled )
   {
-    const PerformanceMarker& marker = mMarkers[i];
-    switch( marker.GetType() )
-    {
-      case START:
-      {
-        mStats.StartTime( marker.GetTimeStamp() );
-        break;
-      }
-      case END:
-      {
-        mStats.EndTime( marker.GetTimeStamp() );
-        break;
-      }
-      default:
-      {
-        break;
-      }
-    }
+    return;
   }
 
-  mMarkers.Clear();
-}
+  // AddMarker can be called from multiple threads, to avoid problems
+  // with updating contexts and the kernel trace, lock here.
+  boost::mutex::scoped_lock sharedDatalock( mDataMutex );
 
-const char* PerformanceServer::GetMarkerName( MarkerType type ) const
-{
-  switch( type )
+  if( markerType == VSYNC )
   {
-    case 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 )
     {
-      return "VSYNC";
-    }
-
-    case START:
-    {
-      return "START";
-    }
-
-    case END:
-    {
-      return "END";
-    }
-
-    default:
-    {
-      DALI_ASSERT_DEBUG( !"Unsupported MarkerType" );
-      return "";
+      mEnvironmentOptions.InstallLogFunction();
+      mLogFunctionInstalled = true;
     }
   }
-}
 
-void PerformanceServer::StatContext::LogMarker( const PerformanceMarker& marker )
-{
-  // Add Marker can be called from any thread
-  boost::mutex::scoped_lock sharedDatalock( mDataMutex );
+  // Get the time
+  unsigned int seconds = 0;
+  unsigned int microseconds = 0;
+  mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
 
-  mMarkers.PushBack( marker );
+  // Create a marker
+  PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ) );
 
-  // Only log on the v-sync thread, so we have less impact on update/render
-  if( marker.GetType() == VSYNC )
-  {
-    // log out every mLogFrequency.
-    // check difference between first and last frame
-    unsigned int microseconds = PerformanceMarker::MicrosecondDiff( mMarkers[0], marker );
-    if( microseconds >= mLogFrequencyMicroseconds )
-    {
-      TimeMarkers();
+  // log it
+  LogMarker(marker, marker.GetName() );
 
-      if( mLog )
-      {
-        LogMarker();
-      }
+  // Add internal marker to statistics context manager
+  mStatContextManager.AddInternalMarker( marker );
 
-      mStats.Reset();     // reset data for statistics
-    }
-  }
 }
 
-void PerformanceServer::StatContext::SetLogFrequency( unsigned int frequencyMicroseconds )
+void PerformanceServer::LogContextStatistics( const char* const text )
 {
-  mLogFrequencyMicroseconds = frequencyMicroseconds;
+  Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, text );
 }
 
-void PerformanceServer::StatContext::EnableLogging( bool enableLogging )
+void PerformanceServer::LogMarker( const PerformanceMarker& marker, const char* const description )
 {
-  mLog = enableLogging;
-}
 
-const char* PerformanceServer::StatContext::GetName() const
-{
-  return mName;
-}
 
-unsigned int PerformanceServer::StatContext::GetId() const
-{
-  return mId;
+
+  // log to kernel trace
+  if( mPerformanceOutputBitmask & OUTPUT_KERNEL_TRACE )
+  {
+    // name will be something like UPDATE_START or UPDATE_END
+    mKernelTrace.Trace( description );
+  }
+
+  // log to Dali log
+  if ( mPerformanceOutputBitmask & OUTPUT_DALI_LOG )
+  {
+    Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo,
+                                    "%d.%06d (seconds), %s\n",
+                                    marker.GetTimeStamp().seconds,
+                                    marker.GetTimeStamp().microseconds,
+                                    description);
+  }
 }
 
+
 } // namespace Internal
 
 } // namespace Adaptor
index 21f7b68..a20ccd9 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali/public-api/common/dali-vector.h>
 #include <base/interfaces/adaptor-internal-services.h>
 #include <base/performance-logging/performance-marker.h>
+#include <base/performance-logging/statistics/stat-context-manager.h>
 
 // EXTERNAL INCLUDES
 #include <boost/thread/mutex.hpp>
@@ -37,20 +38,20 @@ namespace Adaptor
 {
 
 class EnvironmentOptions;
-
+class StatContext;
 /**
  * Concrete implementation of performance interface.
  * Adaptor classes should never include this file, they
  * just need to include the abstract class performance-interface.h
  */
-class PerformanceServer : public PerformanceInterface
+class PerformanceServer : public PerformanceInterface, public StatContextLogInterface
 {
 public:
 
   /**
-   * Constructor
-   * @param adaptorServices adaptor internal services
-   * @param environmentOptions environment options
+   * @brief Constructor
+   * @param[in] adaptorServices adaptor internal services
+   * @param[in] environmentOptions environment options
    */
   PerformanceServer( AdaptorInternalServices& adaptorServices,
                      const EnvironmentOptions& environmentOptions );
@@ -71,19 +72,21 @@ public:
   virtual void RemoveContext( ContextId contextId );
 
   /**
-   * @copydoc PerformanceInterface::AddMarker()
+   * @copydoc PerformanceInterface::AddMarker( MarkerType markerType )
    */
   virtual void AddMarker( MarkerType markerType );
 
   /**
-   * @copydoc PerformanceLogger::AddMarker()
+   * @copydoc PerformanceLogger::AddMarker( MarkerType markerType, ContextId contextId )
    */
   virtual void AddMarker( MarkerType markerType, ContextId contextId );
 
   /**
    * @copydoc PerformanceInterface::SetLogging()
    */
-  virtual void SetLogging( unsigned int level, unsigned int logFrequency );
+  virtual void SetLogging( unsigned int statisticsLogOptions,
+                           unsigned int timeStampOutput,
+                           unsigned int logFrequency );
 
   /**
    * @copydoc PerformanceLogger::SetLoggingFrequency()
@@ -95,133 +98,33 @@ public:
    */
   virtual void EnableLogging( bool enable, ContextId contextId );
 
-private:
+public: //StatLogInterface
 
   /**
-   * Class to hold a stat context
+   * @copydoc StatLogInterface::LogContextStatistics()
    */
-  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
-  };
+  virtual void LogContextStatistics( const char* const text );
 
-  /**
-   * Helper
-   */
-  void AddMarkerToLog( const PerformanceMarker& marker, ContextId contextId );
-
-  /**
-   * 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
-   */
-  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
+   * @brief log the marker out to kernel/ DALi log
+   * @param[in] marker performance marker
+   * @param[in] description marker description
    */
-  const char* GetMarkerName( MarkerType type ) const;
+  void LogMarker( const PerformanceMarker& marker, const char* const description );
 
 private:
 
-  typedef Dali::Vector< StatContext* > StatContexts;
-
-  // The list of stat contexts
-  StatContexts mStatContexts;
-
   Integration::PlatformAbstraction& mPlatformAbstraction; ///< platform abstraction
   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
+  boost::mutex mDataMutex;                                ///< mutex
+  StatContextManager mStatContextManager;                 ///< Stat context manager
+  unsigned int mStatisticsLogBitmask;                     ///< statistics log level
+  unsigned int mPerformanceOutputBitmask;                 ///< performance marker output
+  bool mLoggingEnabled:1;                                 ///< whether logging update / render to a log is enabled
+  bool mLogFunctionInstalled:1;                           ///< whether the log function is installed
 };
 
 
diff --git a/adaptors/base/performance-logging/statistics/stat-context-log-interface.h b/adaptors/base/performance-logging/statistics/stat-context-log-interface.h
new file mode 100644 (file)
index 0000000..c8e9409
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef __DALI_INTERNAL_ADAPTOR_STATISTICS_STAT_CONTEXT_LOG_INTERFACE_H__
+#define __DALI_INTERNAL_ADAPTOR_STATISTICS_STAT_CONTEXT_LOG_INTERFACE_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.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+/**
+ * @brief  Abstract interface used to log statistics data
+ */
+class StatContextLogInterface
+{
+public:
+
+  /**
+   * @brief Used to log statistics out
+   * @param[in] text log the text
+   */
+  virtual void LogContextStatistics( const char* const text) = 0;
+
+
+protected:
+
+  /**
+   * @brief  Constructor
+   */
+  StatContextLogInterface()
+  {
+  }
+
+  /**
+   * @brief Virtual Destructor
+   */
+  virtual ~StatContextLogInterface()
+  {
+  }
+
+private:
+
+  // Undefined copy constructor.
+  StatContextLogInterface( const StatContextLogInterface& );
+
+  // Undefined assignment operator.
+  StatContextLogInterface& operator=( const StatContextLogInterface& );
+
+};
+
+
+} // namespace Internal
+
+} // namespace Adaptor
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_ADAPTOR_STATISTICS_STAT_CONTEXT_LOG_INTERFACE_H__
diff --git a/adaptors/base/performance-logging/statistics/stat-context-manager.cpp b/adaptors/base/performance-logging/statistics/stat-context-manager.cpp
new file mode 100644 (file)
index 0000000..5d7146e
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2015 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 "stat-context-manager.h"
+
+// INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+namespace
+{
+const char* const UPDATE_CONTEXT_NAME = "Update";
+const char* const RENDER_CONTEXT_NAME = "Render";
+const char* const EVENT_CONTEXT_NAME = "Event";
+const unsigned int DEFAULT_LOG_FREQUENCY = 2;
+}
+
+StatContextManager::StatContextManager( StatContextLogInterface& logInterface )
+: mLogInterface( logInterface ),
+  mNextContextId( 0 ),
+  mStatisticsLogBitmask(0),
+  mLogFrequency( DEFAULT_LOG_FREQUENCY )
+{
+
+  mStatContexts.Reserve(4); // intially reserve enough for 3 internal + 1 custom
+
+  // Add defaults
+  mUpdateStats = AddContext( UPDATE_CONTEXT_NAME, PerformanceMarker::UPDATE );
+  mRenderStats = AddContext( RENDER_CONTEXT_NAME, PerformanceMarker::RENDER );
+  mEventStats = AddContext( EVENT_CONTEXT_NAME,   PerformanceMarker::EVENT_PROCESS );
+
+}
+
+StatContextManager::~StatContextManager()
+{
+  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
+  {
+    StatContext* context = *it;
+    delete context;
+  }
+  mStatContexts.Clear();
+}
+PerformanceInterface::ContextId StatContextManager::AddContext( const char* const name,
+                                                                PerformanceMarker::MarkerFilter type  )
+{
+  unsigned int contextId = mNextContextId++;
+
+  DALI_ASSERT_DEBUG( NULL == GetContext( contextId ) );
+
+  // logging enabled by default
+  StatContext* statContext = new StatContext( contextId, name, type,  mLogFrequency , mLogInterface );
+
+  // check to see if custom markers are enabled
+  if( ! ( mStatisticsLogBitmask & PerformanceInterface::LOG_CUSTOM_MARKERS ) )
+  {
+    statContext->EnableLogging( false );
+  }
+
+  mStatContexts.PushBack( statContext );
+
+  return contextId;
+}
+
+void StatContextManager::AddInternalMarker( const PerformanceMarker& marker )
+{
+  // log to the stat contexts, can be called from multiple threads so we
+  // protect the data
+  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
+  {
+    StatContext* context = *it;
+    context->ProcessInternalMarker( marker );
+  }
+}
+
+void StatContextManager::AddCustomMarker( const PerformanceMarker& marker, PerformanceInterface::ContextId contextId )
+{
+  // log to the stat contexts, can be called from multiple threads so we
+  // protect the data
+  StatContext* context = GetContext( contextId );
+  if( context )
+  {
+    context->ProcessCustomMarker( marker );
+  }
+}
+
+void StatContextManager::RemoveContext(PerformanceInterface::ContextId contextId )
+{
+  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
+  {
+    StatContext* context = *it;
+
+    if( context->GetId() == contextId )
+    {
+      delete context;
+      mStatContexts.Erase( it );
+      return;
+    }
+  }
+}
+
+
+void StatContextManager::EnableLogging( bool enable, PerformanceInterface::ContextId contextId )
+{
+  StatContext* context = GetContext( contextId );
+  if( context )
+  {
+    context->EnableLogging( enable );
+  }
+}
+
+void StatContextManager::SetLoggingLevel(  unsigned int statisticsLogOptions, unsigned int logFrequency)
+{
+  mStatisticsLogBitmask = statisticsLogOptions;
+
+  if( mStatisticsLogBitmask == PerformanceInterface::LOG_EVERYTHING )
+  {
+    mStatisticsLogBitmask = 0xFFFFFFFF; // enable everything
+  }
+
+  mLogFrequency = logFrequency;
+
+  // currently uses DALI_LOG_PERFORMANCE_STATS_FREQ environment variable to determine to log frequency
+  // if it's not set it will be zero
+  if( mLogFrequency == 0 )
+  {
+    mLogFrequency = DEFAULT_LOG_FREQUENCY;
+  }
+  EnableLogging( mStatisticsLogBitmask & PerformanceInterface::LOG_UPDATE_RENDER, mUpdateStats );
+  EnableLogging( mStatisticsLogBitmask & PerformanceInterface::LOG_UPDATE_RENDER, mRenderStats );
+  EnableLogging( mStatisticsLogBitmask & PerformanceInterface::LOG_EVENT_PROCESS, mEventStats );
+
+  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
+  {
+     StatContext* context = *it;
+     context->SetLogFrequency( mLogFrequency );
+  }
+}
+
+void StatContextManager::SetLoggingFrequency( unsigned int logFrequency,
+                                              PerformanceInterface::ContextId contextId  )
+{
+  StatContext* context = GetContext( contextId );
+  if( context )
+  {
+    if( logFrequency == 0 )
+    {
+      logFrequency = DEFAULT_LOG_FREQUENCY;
+    }
+    context->SetLogFrequency( logFrequency );
+  }
+}
+const char* const StatContextManager::GetContextName(PerformanceInterface::ContextId contextId) const
+{
+  StatContext* context = GetContext(contextId);
+  if( context )
+  {
+    return context->GetName();
+  }
+  return "context not found";
+}
+
+const char* const StatContextManager::GetMarkerDescription( PerformanceInterface::MarkerType type, PerformanceInterface::ContextId contextId ) const
+{
+  StatContext* context = GetContext(contextId);
+  if( context )
+  {
+    return context->GetMarkerDescription( type );
+  }
+  return "context not found";
+}
+
+
+StatContext* StatContextManager::GetContext( PerformanceInterface::ContextId contextId ) const
+{
+  for( StatContexts::Iterator it = mStatContexts.Begin(), itEnd = mStatContexts.End(); it != itEnd; ++it )
+  {
+    StatContext* context = *it;
+
+    if( context->GetId() == contextId )
+    {
+      return context;
+    }
+  }
+
+  return NULL;
+}
+
+
+} // namespace Internal
+
+} // namespace Adaptor
+
+} // namespace Dali
+
+
diff --git a/adaptors/base/performance-logging/statistics/stat-context-manager.h b/adaptors/base/performance-logging/statistics/stat-context-manager.h
new file mode 100644 (file)
index 0000000..49242a0
--- /dev/null
@@ -0,0 +1,163 @@
+#ifndef __DALI_INTERNAL_ADAPTOR_STAT_CONTEXT_MANAGER_H__
+#define __DALI_INTERNAL_ADAPTOR_STAT_CONTEXT_MANAGER_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <base/performance-logging/performance-marker.h>
+#include <base/performance-logging/statistics/stat-context.h>
+#include <base/interfaces/performance-interface.h>
+
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+/**
+ * Class to manage StatContext objects.
+ *
+ * Contains 3 built in contexts for event, update, render.
+ * The application developer can add more using the PerformanceLogger public API
+ *
+ * Example output of 4 contexts ( event, update, render and a custom one):
+ *
+ * Event, min 0.04 ms, max 5.27 ms, total (0.1 secs), avg 0.28 ms, std dev 0.73 ms
+ * Update, min 0.29 ms, max 0.91 ms, total (0.5 secs), avg 0.68 ms, std dev 0.15 ms
+ * Render, min 0.33 ms, max 0.97 ms, total (0.6 secs), avg 0.73 ms, std dev 0.17 ms
+ * MyAppTask, min 76.55 ms, max 76.55 ms, total (0.1 secs), avg 76.55 ms, std dev 0.00 ms  (CUSTOM CONTEXT)
+ *
+ */
+class StatContextManager
+{
+
+public:
+
+    /**
+     * @brief Constructor
+     * @param[in] logInterface interface to log statistics to
+     */
+    StatContextManager( StatContextLogInterface& logInterface );
+
+    /**
+     * @brief destructor, not intended as a bass class
+     */
+    ~StatContextManager();
+
+    /**
+     * @brief Add a context
+     * @param[in] name Name of the context to print in console
+     * @param[in] type the type of events to filter ( e.g. event, update, render or custom)
+     * @return The ID to give the context
+     */
+    PerformanceInterface::ContextId AddContext( const char* const name, PerformanceMarker::MarkerFilter type );
+
+    /**
+     * @brief Remove a context
+     * @param[in] contextId id of the context to remove
+     */
+    void RemoveContext(PerformanceInterface::ContextId contextId );
+
+    /**
+     * @brief Add an internal marker (e.g. v-sync, update, render markers)
+     * @param[in] marker the marker to add
+     */
+    void AddInternalMarker( const PerformanceMarker& marker );
+
+    /**
+     * @brief Add a custom marker defined by the application
+     * @param[in] marker the marker to add
+     * @param[in] contextId the context the custom marker is designed for
+     */
+    void AddCustomMarker( const PerformanceMarker& marker , PerformanceInterface::ContextId contextId );
+
+    /**
+     * @brief Get the nane of a context
+     * @param[in] contextId id of the context to get the name
+     * @return context name
+     */
+    const char* const GetContextName( PerformanceInterface::ContextId contextId ) const;
+
+    /**
+     * @brief Get the full description of a marker for this context
+     * @param[in] type marker type, for a customer marker this will be either START or END
+     * @param[in] contextId id of the context to get the name
+     * @return marker description in relation to this context
+     */
+    const char* const GetMarkerDescription( PerformanceInterface::MarkerType type, PerformanceInterface::ContextId contextId ) const;
+
+
+    /**
+     * @brief enable / disable logging for a context
+     * @param[in] enable whether to enable logging
+     * @param[in] contextId the context to configure
+     */
+    void EnableLogging( bool enable, PerformanceInterface::ContextId contextId );
+
+    /**
+     * @brief set global logging level and frequency.
+     * @param[in] statisticsLogOptions  log options
+     * @param[in] logFrequency frequency in seconds
+     */
+    void SetLoggingLevel( unsigned int statisticsLogOptions, unsigned int logFrequency);
+
+    /**
+     * @brief Set the frequency of logging for an individual context
+     * @param[in] logFrequency log frequency in seconds
+     * @param[in] contextId the context to configure
+     */
+    void SetLoggingFrequency( unsigned int logFrequency, PerformanceInterface::ContextId contextId  );
+
+  private:
+
+    typedef Dali::Vector< StatContext* > StatContexts;
+
+    /**
+     * @brief helper
+     * @param[in] contextId the context to get
+     * @return context
+     */
+    StatContext* GetContext( PerformanceInterface::ContextId contextId ) const;
+
+    StatContexts mStatContexts;                        ///< The list of stat contexts
+    StatContextLogInterface& mLogInterface;            ///< Log interface
+
+    PerformanceInterface::ContextId mNextContextId;    ///< The next valid context ID
+
+    // Some defaults contexts
+    PerformanceInterface::ContextId mUpdateStats;    ///< update time statistics
+    PerformanceInterface::ContextId mRenderStats;    ///< render time statistics
+    PerformanceInterface::ContextId mEventStats;     ///< event time statistics
+
+    unsigned int mStatisticsLogBitmask;              ///< statistics log bitmask
+    unsigned int mLogFrequency;                      ///< log frequency
+};
+
+
+} // namespace Internal
+
+} // namespace Adaptor
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_ADAPTOR_STAT_CONTEXT_MANAGER_H__
+
diff --git a/adaptors/base/performance-logging/statistics/stat-context.cpp b/adaptors/base/performance-logging/statistics/stat-context.cpp
new file mode 100644 (file)
index 0000000..468cb28
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2015 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 "stat-context.h"
+
+// INTERNAL INCLUDES
+#include <dali/integration-api/platform-abstraction.h>
+
+namespace Dali
+{
+
+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 MILLISECONDS_PER_SECOND = 1000;    ///< 1000 milliseconds per second
+const char* const UNKNOWN_CONTEXT_NAME = "UNKNOWN_CONTEXT_NAME";
+const unsigned int MICROSECONDS_PER_SECOND = 1000000; ///< 1000000 microseconds per second
+const unsigned int CONTEXT_LOG_SIZE = 120;
+
+}
+
+StatContext::StatContext( unsigned int id,
+                          const char* const contextName,
+                          PerformanceMarker::MarkerFilter contextType,
+                          unsigned int logFrequencySeconds,
+                          StatContextLogInterface& logInterface )
+: mInitialMarker(PerformanceInterface::VSYNC),
+  mName( contextName ),
+  mLogInterface( logInterface ),
+  mNamePlusStart( std::string(contextName) + "_START" ),
+  mNamePlusEnd( std::string(contextName) + "_END" ),
+  mId( id ),
+  mLogFrequencyMicroseconds( logFrequencySeconds * MICROSECONDS_PER_SECOND ),
+  mFilterType( contextType ),
+  mLoggingEnabled( true ),
+  mInitialMarkerSet( false )
+{
+  mTempLogBuffer = new char[ CONTEXT_LOG_SIZE ];
+}
+
+StatContext::~StatContext()
+{
+  delete []mTempLogBuffer;
+}
+unsigned int StatContext::GetId() const
+{
+  return mId;
+}
+
+const char* const StatContext::GetName() const
+{
+  return mName;
+}
+
+const char* const StatContext::GetMarkerDescription( PerformanceInterface::MarkerType type ) const
+{
+  if( type == PerformanceInterface::START )
+  {
+    return mNamePlusStart.c_str();
+  }
+  else if( type == PerformanceInterface::END )
+  {
+    return mNamePlusEnd.c_str();
+  }
+  return UNKNOWN_CONTEXT_NAME;
+}
+void StatContext::SetLogFrequency( unsigned int logFrequencySeconds )
+{
+  mLogFrequencyMicroseconds = logFrequencySeconds * MICROSECONDS_PER_SECOND;
+}
+
+void StatContext::EnableLogging( bool enableLogging )
+{
+  mLoggingEnabled = enableLogging;
+}
+
+void StatContext::ProcessCustomMarker( const PerformanceMarker& marker )
+{
+  // this marker has come from the application PerformanceLogger API
+  RecordMarker( marker);
+}
+
+void StatContext::ProcessInternalMarker( const PerformanceMarker& marker )
+{
+  // this marker has come from DALi internal not the application
+  // see if this context is for update, render or event
+ if( marker.IsFilterEnabled( mFilterType ))
+ {
+   RecordMarker( marker );
+ }
+ // V_SYNC is always processed
+ if( marker.GetType() == PerformanceInterface::VSYNC )
+ {
+   FrameTick( marker );
+ }
+}
+
+void StatContext::RecordMarker( const PerformanceMarker& marker )
+{
+  if( marker.GetEventType() == PerformanceMarker::START_TIMED_EVENT )
+  {
+    mStats.StartTime( marker.GetTimeStamp() );
+  }
+  else if( marker.GetEventType() == PerformanceMarker::END_TIMED_EVENT )
+  {
+    mStats.EndTime( marker.GetTimeStamp() );
+  }
+}
+
+void StatContext::FrameTick( const PerformanceMarker& marker )
+{
+  // wait until we've got some data
+  if( ! mInitialMarkerSet )
+  {
+    mInitialMarker = marker;
+    mInitialMarkerSet = true;
+    return;
+  }
+  // log out every mLogFrequency.
+  // check difference between first and last frame
+  unsigned int microseconds = PerformanceMarker::MicrosecondDiff( mInitialMarker, marker );
+
+  if( microseconds < mLogFrequencyMicroseconds )
+  {
+    return;
+  }
+
+  if( mLoggingEnabled )
+  {
+    LogMarker();
+  }
+  mStats.Reset();             // reset data for statistics
+  mInitialMarkerSet = false;  // need to restart the timer
+
+}
+
+void StatContext::LogMarker()
+{
+  float mean, standardDeviation;
+  mStats.CalculateMean( mean, standardDeviation );
+
+  snprintf( mTempLogBuffer, CONTEXT_LOG_SIZE, "%s, min " TIME_FMT ", max " TIME_FMT ", total (" TOTAL_TIME_FMT "), avg " TIME_FMT ", std dev " TIME_FMT "\n",
+     mName ? mName : UNKNOWN_CONTEXT_NAME,
+     mStats.GetMinTime() * MILLISECONDS_PER_SECOND,
+     mStats.GetMaxTime() * MILLISECONDS_PER_SECOND,
+     mStats.GetTotalTime(),
+     mean * MILLISECONDS_PER_SECOND,
+     standardDeviation * MILLISECONDS_PER_SECOND );
+
+    mLogInterface.LogContextStatistics( mTempLogBuffer );
+
+}
+
+
+
+} // namespace Internal
+
+} // namespace Adaptor
+
+} // namespace Dali
diff --git a/adaptors/base/performance-logging/statistics/stat-context.h b/adaptors/base/performance-logging/statistics/stat-context.h
new file mode 100644 (file)
index 0000000..2e96b9f
--- /dev/null
@@ -0,0 +1,168 @@
+#ifndef __DALI_INTERNAL_ADAPTOR_STAT_CONTEXT_H__
+#define __DALI_INTERNAL_ADAPTOR_STAT_CONTEXT_H__
+
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <base/performance-logging/performance-marker.h>
+#include <base/performance-logging/frame-time-stats.h>
+#include <base/interfaces/performance-interface.h>
+#include <base/performance-logging/statistics/stat-context-log-interface.h>
+
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+/**
+ * Stores and prints statistics for a particular logging context.
+ *
+ */
+class StatContext
+{
+
+public:
+
+    /**
+     * @brief Constructor
+     *
+     * @param[in] id The ID to give the context
+     * @param[in] contextName Name of the context to print in console
+     * @param[in] contextType the type of events to filter ( e.g. event, update, render or custom)
+     * @param[in] logFrequencySeconds frequency to log in seconds
+     * @param[in] logInterface interface to log out to
+     *
+     */
+    StatContext( unsigned int id,
+                 const char* const contextName,
+                 PerformanceMarker::MarkerFilter contextType,
+                 unsigned int logFrequencySeconds,
+                 StatContextLogInterface& logInterface );
+
+
+    /**
+     * @brief Non-virtual destructor, not intended as a base class
+     */
+    ~StatContext();
+
+    /**
+     * @return Return the context ID
+     */
+    unsigned int GetId() const;
+
+    /**
+     * @return the context name
+     */
+    const char* const GetName() const;
+
+    /**
+     *
+     * For logging we want to output the name of the context with either
+     * START / END appended to the end. E.g. MY_MARKER_START
+     * @param[in] type marker type, for a customer marker this will be either START or END
+     * @return the full description for a marker
+     */
+    const char* const GetMarkerDescription( PerformanceInterface::MarkerType type ) const;
+
+    /**
+     * @brief Set the frequency for logging
+     *
+     * @param[in] logFrequencySeconds The log frequency to set in seconds
+     */
+    void SetLogFrequency( unsigned int logFrequencySeconds );
+
+    /**
+     * @brief enable/disable logging
+     *
+     * @param[in] enableLogging Flag to spePerformancecify enabling/disabling
+     */
+    void EnableLogging( bool enableLogging );
+
+    /**
+     * @brief  Process a custom marker from the application
+     *
+     * @param[in] marker The marker to log
+     */
+    void ProcessCustomMarker( const PerformanceMarker& marker );
+
+    /**
+     * @brief Process a internal marker from DALi (V_SYNC/ UPDATE /RENDER/ EVENT )
+     *
+     * @param[in] marker The marker to log
+     */
+    void ProcessInternalMarker( const PerformanceMarker& marker );
+
+  private:
+
+    /**
+     * @brief Record marker
+     *
+     * @param[in] marker to record
+     */
+    void RecordMarker( const PerformanceMarker& marker );
+
+    /**
+     * @brief Called when V-SYNC occurs to indicate a frame tick
+     * @param[in] marker the marker containing a v-sync
+     */
+    void FrameTick( const PerformanceMarker& marker );
+
+    /**
+     * @brief Helper to print to console
+     */
+    void LogMarker();
+
+
+  private:
+
+    StatContext();                                ///< undefined default constructor
+
+    StatContext( const StatContext& );            ///< undefined copy constructor
+
+    StatContext& operator=( const StatContext& ); ///< undefined assignment operator
+
+  private:
+
+    PerformanceMarker mInitialMarker;             ///< Used to store initial time
+    FrameTimeStats mStats;                        ///< Frame time stats to accumulate
+    const char* const mName;                      ///< Name of the context
+    char* mTempLogBuffer;                         ///< Temporary log buffer
+    StatContextLogInterface& mLogInterface;       ///< Log interface
+    const std::string mNamePlusStart;             ///< Name of the context + _START
+    const std::string mNamePlusEnd;                ///< Name of the context + _END
+    unsigned int mId;                             ///< The ID of the context
+    unsigned int mLogFrequencyMicroseconds;       ///< if logging is enabled, what frequency to log out at in micro-seconds
+    PerformanceMarker::MarkerFilter mFilterType;  ///< type of events the context is filtering
+    bool mLoggingEnabled:1;                       ///< Whether to print the log for this context or not
+    bool mInitialMarkerSet:1;                     ///< Whether the initial marker has been set
+
+};
+
+
+} // namespace Internal
+
+} // namespace Adaptor
+
+} // namespace Dali
+
+#endif
index e0982ca..d12bb01 100644 (file)
@@ -128,13 +128,17 @@ void Adaptor::ParseEnvironmentOptions()
   // get logging options
   unsigned int logFrameRateFrequency = GetIntegerEnvironmentVariable( DALI_ENV_FPS_TRACKING, 0 );
   unsigned int logupdateStatusFrequency = GetIntegerEnvironmentVariable( DALI_ENV_UPDATE_STATUS_INTERVAL, 0 );
-  unsigned int logPerformanceLevel = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PERFORMANCE, 0 );
+  unsigned int logPerformanceStats = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PERFORMANCE_STATS, 0 );
+  unsigned int logPerformanceStatsFrequency = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PERFORMANCE_STATS_FREQUENCY, 0 );
+  unsigned int performanceTimeStampOutput= GetIntegerEnvironmentVariable( DALI_ENV_PERFORMANCE_TIMESTAMP_OUTPUT, 0 );
+
+
   unsigned int logPanGesture = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PAN_GESTURE, 0 );
 
   // all threads here (event, update, and render) will send their logs to SLP Platform's LogMessage handler.
   Dali::Integration::Log::LogFunction  logFunction(Dali::SlpPlatform::LogMessage);
 
-  mEnvironmentOptions.SetLogOptions( logFunction, logFrameRateFrequency, logupdateStatusFrequency, logPerformanceLevel, logPanGesture );
+  mEnvironmentOptions.SetLogOptions( logFunction, logFrameRateFrequency, logupdateStatusFrequency, logPerformanceStats, logPerformanceStatsFrequency, performanceTimeStampOutput, logPanGesture );
 
   int predictionMode;
   if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_PREDICTION_MODE, predictionMode) )
@@ -228,7 +232,7 @@ void Adaptor::Initialize(Dali::Configuration::ContextLoss configuration)
   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
   // files automatically.
 
-  if( mEnvironmentOptions.GetPerformanceLoggingLevel() > 0 )
+  if( mEnvironmentOptions.PerformanceServerRequired() )
   {
     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, mEnvironmentOptions );
   }