[dali_1.0.1] Merge branch 'tizen'
[platform/core/uifw/dali-adaptor.git] / adaptors / base / performance-logging / performance-server.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "performance-server.h"
20
21 // INTERNAL INCLUDES
22 #include <base/environment-options.h>
23
24 namespace Dali
25 {
26
27 namespace Internal
28 {
29
30 namespace Adaptor
31 {
32
33 #define TIME_FMT "%0.2f ms" // 2 decimal places, e.g. 5.34 ms
34 #define TOTAL_TIME_FMT "%0.1f secs" // 1 decimal place, e.g. 4.5 seconds
35
36
37 namespace
38 {
39 const unsigned int DEFAULT_LOG_FREQUENCEY = 2;        ///< default log frequency = 2
40 const unsigned int MILLISECONDS_PER_SECOND = 1000;    ///< 1000 milliseconds per second
41 const unsigned int MICROSECONDS_PER_SECOND = 1000000; ///< 1000000 microseconds per second
42 }
43
44
45 PerformanceServer::PerformanceServer( AdaptorInternalServices& adaptorServices,
46                                       const EnvironmentOptions& environmentOptions)
47 :mLoggingEnabled( false),
48  mLogFunctionInstalled( false ),
49  mLogFrequencyMicroseconds( 0),
50  mPlatformAbstraction( adaptorServices.GetPlatformAbstractionInterface() ),
51  mEnvironmentOptions(environmentOptions),
52  mKernelTrace( adaptorServices.GetKernelTraceInterface() )
53 {
54   SetLogging( mEnvironmentOptions.GetPerformanceLoggingLevel(), mEnvironmentOptions.GetFrameRateLoggingFrequency());
55 }
56
57 PerformanceServer::~PerformanceServer()
58 {
59   if( mLogFunctionInstalled )
60   {
61     mEnvironmentOptions.UnInstallLogFunction();
62   }
63 }
64 void PerformanceServer::SetLogging( unsigned int level, unsigned int interval)
65 {
66   if( level == 0)
67   {
68     mLoggingEnabled = false;
69     return;
70   }
71   mLogLevel = level;
72
73   mLogFrequencyMicroseconds = interval * MICROSECONDS_PER_SECOND;
74
75   if( mLogFrequencyMicroseconds == 0 )
76   {
77     mLogFrequencyMicroseconds = DEFAULT_LOG_FREQUENCEY * MICROSECONDS_PER_SECOND;
78   }
79   mLoggingEnabled = true;
80
81 }
82
83 void PerformanceServer::AddMarker( PerformanceMarker::MarkerType markerType )
84 {
85   if( !mLoggingEnabled )
86   {
87     return;
88   }
89
90   unsigned int seconds(0);
91   unsigned int microseconds(0);
92
93   // get the time
94   mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
95
96   // create a marker
97   PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ));
98
99   AddMarkerToLog( marker );
100 }
101
102 void PerformanceServer::AddMarkerToLog( PerformanceMarker marker )
103 {
104   // Add Marker can be called from any thread
105   boost::mutex::scoped_lock sharedDatalock( mDataMutex );
106
107   // store the marker
108   mMarkers.PushBack( marker );
109
110   if( mLogLevel & LOG_EVENTS_TO_KERNEL )
111   {
112     mKernelTrace.Trace(marker.GetName());
113   }
114
115   // only log on the v-sync thread, so we have less impact on update/render
116   if( marker.GetType() != PerformanceMarker::V_SYNC )
117   {
118     return;
119   }
120
121   // log out every mLogFrequency.
122   // check difference between first and last frame
123   unsigned int microseconds = PerformanceMarker::MicrosecondDiff( mMarkers[0], marker );
124
125   if( microseconds  >=  mLogFrequencyMicroseconds )
126   {
127     LogMarkers( );
128     mMarkers.Clear();
129
130     // reset data for update / render statistics
131     mUpdateStats.Reset();
132     mRenderStats.Reset();
133     mEventStats.Reset();
134   }
135 }
136
137 void PerformanceServer::LogMarker(const char* name, const FrameTimeStats& frameStats)
138 {
139   // make sure log function is installed, note this will be called only from v-sync thread
140   // if the v-sync thread has already installed one, it won't make any difference.
141   if(! mLogFunctionInstalled )
142   {
143     mEnvironmentOptions.InstallLogFunction();
144     mLogFunctionInstalled = true;
145   }
146
147   // this will always log regardless of debug / release mode
148   Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo,
149                                     "%s , min " TIME_FMT ", max " TIME_FMT ", total (" TOTAL_TIME_FMT "), avg " TIME_FMT "\n",
150                                      name,
151                                      frameStats.GetMinTime() * MILLISECONDS_PER_SECOND,
152                                      frameStats.GetMaxTime() * MILLISECONDS_PER_SECOND,
153                                      frameStats.GetTotalTime(),
154                                      frameStats.GetRollingAverageTime() * MILLISECONDS_PER_SECOND);
155 }
156
157 void PerformanceServer::LogMarkers()
158 {
159   // insert time stamps into a frame-time-stats object, based on type
160   for( MarkerVector::SizeType i = 0; i < mMarkers.Size(); ++i)
161   {
162     const PerformanceMarker& marker = mMarkers[i];
163     switch( marker.GetType() )
164     {
165       case PerformanceMarker::UPDATE_START:
166       {
167         mUpdateStats.StartTime( marker.GetTimeStamp() );
168         break;
169       }
170       case PerformanceMarker::UPDATE_END:
171       {
172         mUpdateStats.EndTime( marker.GetTimeStamp() );
173         break;
174       }
175       case PerformanceMarker::RENDER_START:
176       {
177         mRenderStats.StartTime( marker.GetTimeStamp() );
178         break;
179       }
180       case PerformanceMarker::RENDER_END:
181       {
182         mRenderStats.EndTime( marker.GetTimeStamp() );
183         break;
184       }
185       case PerformanceMarker::PROCESS_EVENTS_START:
186       {
187         mEventStats.StartTime( marker.GetTimeStamp() );
188         break;
189       }
190       case PerformanceMarker::PROCESS_EVENTS_END:
191       {
192         mEventStats.EndTime( marker.GetTimeStamp() );
193         break;
194       }
195       default:
196       {
197         break;
198       }
199     }
200   }
201   if( mLogLevel & LOG_UPDATE_RENDER )
202   {
203     LogMarker("Update",mUpdateStats);
204     LogMarker("Render",mRenderStats);
205   }
206   if( mLogLevel & LOG_EVENT_PROCESS )
207   {
208     LogMarker("Event",mEventStats);
209   }
210
211 }
212
213 } // namespace Internal
214
215 } // namespace Adaptor
216
217 } // namespace Dali