[dali_2.3.32] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / common / stat-context.cpp
1 /*
2  * Copyright (c) 2015 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 <dali/internal/system/common/stat-context.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstdio>
23
24 // INTERNAL INCLUDES
25 #include <dali/integration-api/platform-abstraction.h>
26
27 namespace Dali
28 {
29 namespace Internal
30 {
31 namespace Adaptor
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 namespace
37 {
38 const unsigned int MILLISECONDS_PER_SECOND = 1000; ///< 1000 milliseconds per second
39 const char* const  UNKNOWN_CONTEXT_NAME    = "UNKNOWN_CONTEXT_NAME";
40 const unsigned int MICROSECONDS_PER_SECOND = 1000000; ///< 1000000 microseconds per second
41 const unsigned int CONTEXT_LOG_SIZE        = 120;
42
43 } // namespace
44
45 StatContext::StatContext(unsigned int                    id,
46                          const char* const               contextName,
47                          PerformanceMarker::MarkerFilter contextType,
48                          unsigned int                    logFrequencySeconds,
49                          StatContextLogInterface&        logInterface)
50 : mInitialMarker(PerformanceInterface::VSYNC),
51   mName(contextName),
52   mLogInterface(logInterface),
53   mNamePlusStart(std::string(contextName) + "_START"),
54   mNamePlusEnd(std::string(contextName) + "_END"),
55   mId(id),
56   mLogFrequencyMicroseconds(logFrequencySeconds * MICROSECONDS_PER_SECOND),
57   mFilterType(contextType),
58   mLoggingEnabled(true),
59   mInitialMarkerSet(false)
60 {
61   mTempLogBuffer = new char[CONTEXT_LOG_SIZE];
62 }
63
64 StatContext::~StatContext()
65 {
66   delete[] mTempLogBuffer;
67 }
68 unsigned int StatContext::GetId() const
69 {
70   return mId;
71 }
72
73 const char* StatContext::GetName() const
74 {
75   return mName;
76 }
77
78 const char* StatContext::GetMarkerDescription(PerformanceInterface::MarkerType type) const
79 {
80   if(type == PerformanceInterface::START)
81   {
82     return mNamePlusStart.c_str();
83   }
84   else if(type == PerformanceInterface::END)
85   {
86     return mNamePlusEnd.c_str();
87   }
88   return UNKNOWN_CONTEXT_NAME;
89 }
90 void StatContext::SetLogFrequency(unsigned int logFrequencySeconds)
91 {
92   mLogFrequencyMicroseconds = logFrequencySeconds * MICROSECONDS_PER_SECOND;
93 }
94
95 void StatContext::EnableLogging(bool enableLogging)
96 {
97   mLoggingEnabled = enableLogging;
98 }
99
100 void StatContext::ProcessCustomMarker(const PerformanceMarker& marker)
101 {
102   // this marker has come from the application PerformanceLogger API
103   RecordMarker(marker);
104 }
105
106 void StatContext::ProcessInternalMarker(const PerformanceMarker& marker)
107 {
108   // this marker has come from DALi internal not the application
109   // see if this context is for update, render or event
110   if(marker.IsFilterEnabled(mFilterType))
111   {
112     RecordMarker(marker);
113   }
114   // V_SYNC is always processed
115   if(marker.GetType() == PerformanceInterface::VSYNC)
116   {
117     FrameTick(marker);
118   }
119 }
120
121 void StatContext::RecordMarker(const PerformanceMarker& marker)
122 {
123   if(marker.GetEventType() == PerformanceMarker::START_TIMED_EVENT)
124   {
125     mStats.StartTime(marker.GetTimeStamp());
126   }
127   else if(marker.GetEventType() == PerformanceMarker::END_TIMED_EVENT)
128   {
129     mStats.EndTime(marker.GetTimeStamp());
130   }
131 }
132
133 void StatContext::FrameTick(const PerformanceMarker& marker)
134 {
135   // wait until we've got some data
136   if(!mInitialMarkerSet)
137   {
138     mInitialMarker    = marker;
139     mInitialMarkerSet = true;
140     return;
141   }
142   // log out every mLogFrequency.
143   // check difference between first and last frame
144   unsigned int microseconds = PerformanceMarker::MicrosecondDiff(mInitialMarker, marker);
145
146   if(microseconds < mLogFrequencyMicroseconds)
147   {
148     return;
149   }
150
151   if(mLoggingEnabled)
152   {
153     LogMarker();
154   }
155   mStats.Reset();            // reset data for statistics
156   mInitialMarkerSet = false; // need to restart the timer
157 }
158
159 void StatContext::LogMarker()
160 {
161   float mean, standardDeviation;
162   mStats.CalculateMean(mean, standardDeviation);
163
164   snprintf(mTempLogBuffer,
165            CONTEXT_LOG_SIZE,
166            "%s, min " TIME_FMT ", max " TIME_FMT ", total (" TOTAL_TIME_FMT "), avg " TIME_FMT ", std dev " TIME_FMT "\n",
167            mName ? mName : UNKNOWN_CONTEXT_NAME,
168            mStats.GetMinTime() * MILLISECONDS_PER_SECOND,
169            mStats.GetMaxTime() * MILLISECONDS_PER_SECOND,
170            mStats.GetTotalTime(),
171            mean * MILLISECONDS_PER_SECOND,
172            standardDeviation * MILLISECONDS_PER_SECOND);
173
174   mLogInterface.LogContextStatistics(mTempLogBuffer);
175 }
176
177 } // namespace Adaptor
178
179 } // namespace Internal
180
181 } // namespace Dali