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