Merge changes I8f46f597,I74e17e92 into devel/master
[platform/core/uifw/dali-adaptor.git] / adaptors / base / performance-logging / frame-time-stats.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 // STRUCT HEADER
19 #include "frame-time-stats.h"
20
21 // EXTERNAL INCLUDES
22 #include <cmath>
23
24 namespace Dali
25 {
26
27 namespace Internal
28 {
29
30 namespace Adaptor
31 {
32
33 namespace
34 {
35 const float EPSILON = 0.9f; // rolling average = (average * epsilon) + (current * epsilon)
36 const float ONE_OVER_MICROSECONDS_TO_SECONDS = 1.f / 1000000.f; ///< microseconds per second
37 }
38
39 FrameTimeStats::FrameTimeStats()
40 : mTotal( 0.f)
41 {
42   mSamples.Reserve( 16 );   // Fill out a little to avoid early reallocations
43
44   Reset();
45 }
46
47 FrameTimeStats::~FrameTimeStats()
48 {
49 }
50
51 void FrameTimeStats::StartTime( const FrameTimeStamp& timeStamp )
52 {
53   // check to make sure we don't get 2 start times in a row
54   if( mTimeState != WAITING_FOR_START_TIME )
55   {
56     Reset();
57   }
58
59   mStart = timeStamp;
60   mTimeState = WAITING_FOR_END_TIME;
61 }
62
63 void FrameTimeStats::EndTime( const FrameTimeStamp& timeStamp )
64 {
65   if( mTimeState != WAITING_FOR_END_TIME )
66   {
67     Reset();
68     return;
69   }
70
71   mTimeState = WAITING_FOR_START_TIME;
72   mRunCount++;
73
74   // frame time in seconds
75   unsigned int elapsedTime = FrameTimeStamp::MicrosecondDiff( mStart, timeStamp);
76
77   mSamples.PushBack( elapsedTime );
78
79   // if the min and max times haven't been set, do that now.
80   if( !mMinMaxTimeSet )
81   {
82     mMin = elapsedTime;
83     mMax = elapsedTime;
84     mMinMaxTimeSet = true;
85   }
86   else
87   {
88     if (elapsedTime < mMin)
89     {
90       mMin= elapsedTime;
91     }
92     else if (elapsedTime > mMax)
93     {
94       mMax = elapsedTime;
95     }
96   }
97
98   mTotal += elapsedTime;
99 }
100
101 void FrameTimeStats::Reset()
102 {
103   mTimeState = WAITING_FOR_START_TIME;
104   mMinMaxTimeSet = false;
105   mMin = 0.f;
106   mMax = 0.f;
107   mRunCount = 0;
108   mSamples.Clear();
109 }
110
111 float FrameTimeStats::GetMaxTime() const
112 {
113   return mMax * ONE_OVER_MICROSECONDS_TO_SECONDS;
114 }
115
116 float FrameTimeStats::GetMinTime() const
117 {
118   return mMin * ONE_OVER_MICROSECONDS_TO_SECONDS;
119 }
120
121 float FrameTimeStats::GetTotalTime() const
122 {
123   return mTotal * ONE_OVER_MICROSECONDS_TO_SECONDS;
124 }
125
126 unsigned int FrameTimeStats::GetRunCount() const
127 {
128   return mRunCount;
129 }
130
131 void FrameTimeStats::CalculateMean( float& meanOut, float& standardDeviationOut ) const
132 {
133   if( mSamples.Size() > 0 )
134   {
135     // Mean
136     unsigned int sum = 0;
137     for( Samples::ConstIterator it = mSamples.Begin(), itEnd = mSamples.End(); it != itEnd; ++it )
138     {
139       unsigned int value = *it;
140
141       sum += value;
142     }
143
144     meanOut = static_cast<float>(sum) / mSamples.Size();
145
146     // Variance
147     float variance = 0.0f;
148     for( Samples::ConstIterator it = mSamples.Begin(), itEnd = mSamples.End(); it != itEnd; ++it )
149     {
150       unsigned int value = *it;
151
152       float difference = static_cast<float>(value) - meanOut;
153
154       variance += difference * difference;
155     }
156
157     variance /= mSamples.Size();
158
159     // Standard deviation
160     standardDeviationOut = sqrtf( variance );
161
162     meanOut *= ONE_OVER_MICROSECONDS_TO_SECONDS;
163     standardDeviationOut *= ONE_OVER_MICROSECONDS_TO_SECONDS;
164   }
165   else
166   {
167     meanOut = 0.0f;
168     standardDeviationOut = 0.0f;
169   }
170 }
171
172
173 } // namespace Adaptor
174
175 } // namespace Internal
176
177 } // namespace Dali